# Unity 引擎入门实践
来源:互联网 发布:9377皇图翅膀进阶数据 编辑:程序博客网 时间:2024/06/11 23:51
关键词:Unity / 入门 / 游戏对象 / 场景 / 快捷键 / Terrain / 资源包
1. 游戏对象和基本操作 #
1.1 场景和游戏对象 #
游戏项目 | / \ 场景A 场景B ... ... | / \ 游戏对象1 游戏对象2 ... ... | / \ 组件 组件 ... ...
场景显示在 Scene 里面,Hierarchy 里面是游戏对象比如 3D Object: Main Camera、Plane等;
按住 Q/W/E/R/T 同时点击鼠标操作:Q平移场景/W平移选中的游戏对象/E旋转/R缩放工具/T操作2D的精灵工具,分别对应 Unity 编辑器左上角的功能图标的快捷键;
鼠标右键:移动视图;
[游戏对象]
- 一个游戏项目由多个场景组成,在场景中,一个角色,一个模型,一个特效,都是游戏对象。
- 场景就是由多个游戏对象组成的;
- 每个游戏对象身上都会有多个组件,使游戏对象具备相应的特性、实现相应的功能;
1.2 快捷键操作 #
- 选中任何游戏对象,按F键或者双击,都可以定位到该游戏对象;
- 按下鼠标右键 + WASD 键进行场景漫游;
- 按下 Alt + 鼠标左键旋转视角;
- 按下鼠标右键旋转视角;
- QWERT工具分别是手型工具、平移工具、旋转工具、缩放工具和 2D 工具;
1.3 Terrain 地形系统 #
- 提升/下沉地形工具
- 平坦地形工具
- 平滑地形工具
- 植树工具
- 地表细节工具
从网上找一些地形贴图资源,自己使用地形编辑器编辑一个新的地图;
1.4 资源包的导入 #
.unitypackage 后缀文件
1.5 摄像机 #
在Unity中摄像机决定游戏最终的显示效果
同一个场景中允许存在多个摄像机
1.6 世界坐标系和本地坐标系 #
世界坐标 Global 是整个 3D 场景的坐标系;
本地坐标 Local 是某个游戏对象内独立的坐标系;
(游戏对象可以有子对象,世界坐标与本地坐标是相对的)
1.7 网格
要想让模型出来,网格是必须的(好比人的骨架);
1.8 纹理
使模型表面赋有更多的细节,就需要给它添加纹理;
比如:在Assets中新建一个material材质球 拖拽到 Object 上,通过右侧的面板修改材质球上的纹理属性间接修改Object
1.9 材质和着色器
材质能够将纹理应用在模型上,着色器决定纹理呈现出的最终效果;
2. 工程与应用程序 #
项目目录下:
- Assets 里面存放的是项目所需要的资源;
- Library 里面存放的是所需要的库文件;
- ProjectSettings 里面存放的是工程设置文件;
- Temp 里面存放的是临时文件;
项目框架:
一个工程里面有多个场景,一个场景中有多个游戏对象,每个游戏对象又有多个组件;
工程(Project) | / \ 场景(Scene) 场景(Scene) ... ... | / \ 游戏对象(GameObject) 游戏对象(GameObject) ... ... | / \ 组件(Component) 组件(Component) ... ...
每个场景可以理解为每个界面;
组件开发:
游戏物体想要实现什么功能,只需要添加对应的组件即可,我们可以在Inspector视图中查看当前游戏对象身上的组件,修改组件的属性; (Inspector)
- Transform 组件,决定物体的位置,旋转和缩放;
- Mesh Filter 组件,显示网格;
- Box Collider 组件,用来给物体添加碰撞器;
- Mesh Renderer 组件,可以给物体添加材质,纹理以及渲染的方式;
脚本组件:
脚本也是一种特殊的组件;
创建脚本;
在脚本中设置公共字段作为组件属性;
在脚本中通过方法获取游戏对象和组件;
用Mono编辑脚本
using UnityEngine;using System.Collections;// 如果我们的脚本需要挂载到游戏对象身上,就需要继承于 MonoBehaviourpublic class TestCS : MonoBehaviour { public int age; public string name; // Use this for initialization void Start () { // gameObject 表示当前脚本组件所挂载的游戏对象 // unity 中输出到控制台使用 print 或者 Debug.log print ("Test 脚本挂在到了 " + gameObject.name + " 的身上"); // 每个游戏对象上都至少有一个组件,叫做 Transform // transform 表示当前游戏对象身上的 Transform 组件 print(transform.position.x); print(name + age); } // Update is called once per frame void Update () { }}
运行结果:
对应的Inspector:
可以再添加一个脚本Demo.cs,修改TestCS.cs的属性,可以改变Cube的Script内容
using UnityEngine;using System.Collections;public class Demo : MonoBehaviour { // Use this for initialization void Start () { // GameObject de fangfa GetComponent, nenggou // huoqu dangqian youxi duixiang shenshang zhiding de leixing de zujian duixiang TestCS t = GetComponent<TestCS> (); t.age = 24; t.name = "Da Wang"; t.Log(); } // Update is called once per frame void Update () { }}
结果截图:
3. Unity 脚本 #
3.1 生命周期 #
Awake –> OnEnable –> Start
==》Update –> LateUpdate ==》
OnDisable –> OnDestroy
using UnityEngine;using System.Collections;// 继承于 MonoBehaviour 的类叫做运行时类,运行时类都不能手动实例化,eg:不能 new: Test t = new Test()public class Test : MonoBehaviour{ // 这些方法都不是 MonoBehaviour 中定义的方法,而是通过反射调用的一些事件。方法名写错不会报错 // 这些方法定义了一个脚本从被加载到被销毁的过程中,脚本的生命周期 // 1.每当脚本被加载时调用,调用 1 次;在Awake中做一些初始化操作(放 public 字段); void Awake () { // 初始化 public 成员 print ("Awake"); } // 2. 在每次激活脚本的时候就会调用 OnEnable,比如计时器重置; void OnEnable () { print ("onEnable"); } // 2. 在第一次调用 Update 之前调用一次 Start 方法,然后中途不管激活取消激活,都不会再调用了 // 在Start方法中也可以做一些初始化操作(主要放私有字段); void Start () { print ("Start"); } // 3.每帧都会调用一次 Update,每秒接近60帧,所以每秒大概调用60次左右 void Update () { print ("Update"); } // 4. 在Update调用之后进行调用,刷新其它逻辑的时候 void LateUpdate () { print ("LateUpdate"); } // 5. 取消激活状态后调用 void OnDisable () { print ("OnDisable"); } // 6.被销毁时调用一次 void OnDestroy () { print ("OnDestroy"); } // 用来写 UI 的,持续调用 - 调用频率高 IMGUI代码需要写在 OnGUI 方法中 void OnGUI () { print ("OnGUI"); } // 以固定的频率调用(跟图像刷新无关,不受图像刷新帧速率的影响) // 一般把处理物理的代码放在这里 void FixedUpdate () { print ("FixedUpdate"); }}//public class A{// public void T(){// Test t = new Test ();// wrong// }//}
3.2 Input 类 #
Input 获取键盘事件:
- Input.GetKey()
- Input.GetKeyDown()
- Input.GetKeyUp()
using UnityEngine;using System.Collections;// 继承于 MonoBehaviour 的类叫做运行时类,运行时类都不能手动实例化,eg:不能 new: Test t = new Test()public class Test : MonoBehaviour{ void Start () { // print ("Start"); } // 获取用户事件需要使用 Input 类 // GetKeyDown 按键按下 & GetKeyUp 按键弹起 & GetKey 检测持续按键的事件 void Update () { // 每帧都需要监听用户事件 // 在当前这一帧中如果用户按下了 W 就会返回 true, 否则返回 false if (Input.GetKeyDown (KeyCode.W)) { print ("往前走."); }else if(Input.GetKeyDown(KeyCode.S)){ // Debug.Log ("往后退."); print ("往后退.");// print 只能在 MonoBehaviour 的子类中使用 } if(Input.GetKeyUp(KeyCode.Alpha1)){ print ("弹起了 1 键"); } if(Input.GetKey(KeyCode.F)){ print ("按了 F 键"); } // GetMouseButtonDown用来检测鼠标按键按下的事件 & // 参数 0 表示鼠标左键 & 参数 1 表示鼠标右键 & 参数 2 表示中键 if(Input.GetMouseButtonDown(0)){ print ("按下了鼠标左键"); } if(Input.GetMouseButtonUp(0)){ print ("弹起了鼠标左键"); } if(Input.GetMouseButton(0)){ print("持续按下了鼠标左键"); } }}
结果截图:
Name Tag ActiveSelf SetActive() GetComponent() AddComponent()
GetComponent() AddComponent()
Destroy() FindGameObjectWithTag() FindGameObjectsWithTag()
3.3. GameObject #
using UnityEngine;using System.Collections;// 继承于 MonoBehaviour 的类叫做运行时类,运行时类都不能手动实例化,eg:不能 new: Test t = new Test()public class Test : MonoBehaviour{ // GameObject - 游戏对象类 void Start () { // 通过 gameObject 获取当前脚本所挂载的游戏对象 // 一般来说, 在属性视图中能够看到或修改的属性, 也能够在脚本中进行获取并且修改 // 1. 获取 & 设置游戏对象的名字 print ("gameObject.name => " + gameObject.name); gameObject.name = "小胡 Cube"; print ("经修改的 gameObject.name => " + gameObject.name); //2. 获取 & 设置游戏对象的 Tag print ("gameObject.tag => " + gameObject.tag); gameObject.tag = "Player"; print ("经修改的 gameObject.tag => " + gameObject.tag); // 3. 获取 & 设置当前游戏对象的激活状态 print ("gameObject.activeSelf 是否激活 => " + gameObject.activeSelf); gameObject.SetActive (false); print ("经重置的 gameObject.activeSelf 是否激活 => " + gameObject.activeSelf); // 4. 获取游戏对象身上的组件 eg: transform // 在 Test.cs 中获取 CubeController 组件 CubeController c = gameObject.GetComponent<CubeController> (); print (c.balabala); // 获取组件 Light l = gameObject.AddComponent<Light> (); // 添加组件 // 5. 通过 tag 的值查找游戏对象 GameObject g = GameObject.FindGameObjectWithTag ("Player"); g.name = "小胡 Sphere"; // 另一种写法 GameObject gg = GameObject.FindWithTag ("Player"); // 6. 通过游戏对象名查找游戏对象 GameObject ggg = GameObject.Find ("Main Camera"); ggg.name = "主摄像机"; // 7. 通过 tag 值查找多个游戏对象 GameObject[] gs = GameObject.FindGameObjectsWithTag("Player"); } void update () {// if (Input.GetKeyDown (KeyCode.S)) {// // 2 秒钟之后销毁游戏对象// GameObject.Destroy (gameObject, 2f);// } }}
using UnityEngine;using System.Collections;public class CubeController : MonoBehaviour { public string balabala;}
运行结果
4. Unity 常识知识点总结 #
4.1 关于程序 #
基本组成:
- Sence 场景,类似于 Flash 中的 stage, 用于放置各种对象
- GameObject, 可以携带各种 Component;
每个 GameObject 至少带有 Transform 组件, 所有的组件都可以从顶部菜单 Component 里面找到并添加给游戏对象;
脚本语言:
- C# / Javascript / boo (前两者使用较为广泛, 网上教程以前两者为主, 个人推荐 C#),一般的继承 MonoBehavior 类的脚本都需要依附的场景中的对象上才能被执行.
GUI(用户图形界面):
- 用于制作按钮/文本显示/滚动条/下拉框等常用图形操作界面元素,使用 GUISkin 和 GUIStyle 可以自定义样式;
- 系统自带 GUI;
- 各类 GUI 插件, NGUI/EZGUI 等;
预制:
- 用于程序运行时,动态实例化对象的”母体”,比如,在射击类游戏中,子弹的生成就可以使用实例化预制的方式来实现,可以定义它的各种属性方法, 然后在使用的时候直接实例化一个实例;
- 在 project 面板右击选择 Create -> Prefab 新建一个预制, 将 Hierarchy 面板中要制成的对象拖到这个新建预制上即可;
标签:
tag 用于辨别物体, 与 name 类似,使用对象的 tag 和 name 都可以找到对应的物体, GameObject.Find(“name”) 或 GameObject.FindWithTag(“Tag”); 默认的是 Untagged,可以通过 Inspector 面板里面 Tag 的下拉菜单选择 Add Tag 项来添加新的标签; Inspector -> TagManager -> Tags 里的 size 来增加标签的数量, 每个 Element 内都填入新标签的名字;
层:
在使用某些功能的时候, 可以通过层来过滤不需要运用该功能的对象, 也就是把该功能运用到特定的层, 比如, 相机的 Culling Mask 属性, 通过选择特定层可以实现只显示位于被选中的层的对象.
层的添加也是在标签管理器中, Unity 已经设置了8个层,你是不能对这8个层进行修改的,你可以从第9个(也就是 user layer8)开始添加你定义的层;
资源:
- .unitypackage 格式的文件可以直接 import 到 unity 中,记住最好是在打开 unity 的情况下,在 project 面板里右击,然后在 import packages 中选中你要导入的资源;
- 可以 export package 导出场景成为 .unitypackage 资源包
在工程面板可以 import new assests 可以导入其他形式的资源, 如, 模型/音频/视频等, 也可直接从外部文件夹中拖入
物理引擎:
unity 使用 nvidia PhysX 物理引擎
碰撞器: 各种基本体的碰撞器(box/sphere/capsule/cylinder), 网格碰撞器(mesh collider),车轮碰撞器(Wheel collider),地形碰撞器(terrain collider) 碰撞器组件在你选中对象的时候会以绿色框显示;
- 碰撞检测: 碰撞器碰撞检测 / 光线投射(射线) / 触发器碰撞检测, 通过碰撞检测可以得到与当前对象发生碰撞的对象信息, 使用碰撞的相关函数 OnCollisionEnter(碰撞器碰撞检测) / OnTriggerEnter(触发器碰撞检测) / Physics.Raycast(光线投射)获取;
- 刚体: 模拟物体物理现象的基础, 加了刚体组件才能模拟重力 / 阻力等;
力: 作用于刚体,你只要通过添加各种力, 就可以使刚体表现出跟现实中一样的受力情况;
粒子系统:
两种形式, 一种以物体携带例子系统组件的形式实现, 另一种是直接使用粒子系统 GameObject(3.5 以后)
- 粒子系统 GameObject: GameObject – Create Other – Particle System
粒子系统组件: 粒子发射器(Particle Emitter, 有 Ellipsoid Particle Emitter 和 Mesh Particle Emitter 两种类型的粒子发射器, 主要有 粒子产生 / 数量 / 速度 / 大小 / 存活时间等参数设置), 粒子动画器(Particle Animator, 主要负责粒子产生后直至粒子消亡的行为变化的控制, 包括运动过程中的旋转 / 受力等), 粒子渲染器(Particle Renderer, 主要是负责给予粒子的渲染,阴影,材质等设定)
Camera(相机):
相机视角: 透视(可调整透视角度) / 正交(没有透视效果)
- Skybox: 只在 Game 窗口可见, 需要 skybox 类型的 shader, 以及附在其上的六面贴图纹理
- 第一人称视角: 角色不出现在视野中, 相机看到的就像角色双眼看到的一样
- 第三人称视角: 能在视野中看到角色, 相机一直跟着角色运动.
可以使用导入 Unity 自带的 Character Controllers 资源包, 里面有第一人称和第三人称的原型
光照系统:
- 常见灯光类型: 平行光(Directional light, 无衰减, 模拟太阳光)
- 聚光灯(spotlight, 从一点向某一方向反射锥形光束, 有衰减, 聚光效果)
- 点光源(Point light, 从一点向外辐射, 有衰减)
- 烘焙: 将静态光影效果渲染到纹理上, 减少灯光和阴影带来的开销
- 阴影: 分为 hard shadows 和 soft shadows 两种, 前一种阴影比较重, 后一种相对柔和.
- 要产生阴影,还需要将投射阴影的对象的 Cast shadows 都选, 将接受阴影的对象的 Receive shadows 勾选, eg: 你要让树在地面上产生阴影, 那就得让树投射阴影, 然后让地面接受阴影才行;
地形系统:
选择顶部菜单 Terrain – creat terrain 创建一个地形
地形有一组地形工具用来绘制地形的高度, 生成各种地貌, 并且可以对地表运用纹理, 还可以添加树,草等地表植被.
4.2 关于美术 #
3d 模型 / 材质 / 纹理(贴图)
shader(着色器, Unity 本身拥有几十种 shader, 也可以根据自己的需要使用 shaderLab 语言来编写 shader,一般可以只用 Unity 自带的和网上流传的)
4.3 关于发布 #
关于 Player settings 播放器设置的话这里暂且不多说,发布的时候通过 player setting 进行发布设置,每个平台都有对应的设置参数,根据需要来设置,主要 是关于程序图 标、分辨 率、渲染 等设置, 大家可以 自己试试 (有些参 数只有 pro 版才能设置)。
下面我们来看看 build settings 对话框,左侧是可发布的平台(Unity 跨平台性 很强大,4.0 已支持发布至 10 种平台:IOS、Andriod、Windows、Mac、Linux、 Webplayer、Flash、PS3、Xbox360、Wii u),右侧是对应平台的发布设置,一 般初学的话,只要会发布单机版的和 webplayer 的就差不多了,这两个的话, 右侧的发布选项按照默认的设置就可以,当然单机版要在 Target Platform 中选 择对应的操作系统,webplayer 的话这里我给大家介绍前两个参数,Streamed 顾名思义就是在网络上下载的时候以流的形式,Offline Deployment,这个是 可以在离线(断网)状态下本地运行你的 webplayer 程序(这里需要注意的是, 默认情况下你每次打开 webplayer 程序的时候,浏览器都会自动去访问官网更 新 webplayer 插件,如果你没勾选这个选项而又在没有联网的状态下运行 webplayer 的话是无法运行的)
End.
Note by HF.
- # Unity 引擎入门实践
- Unity 3d入门实践笔记
- Unity手游引擎安全解析及实践
- Unity引擎制作的游戏接入腾讯WeGame快速入门
- Unity引擎初探
- Unity (游戏引擎)
- Unity引擎初探
- Unity物理引擎:力场
- Unity引擎基础
- Unity 引擎源代码
- Unity引擎学习
- unity引擎基础
- Unity入门
- Unity入门
- Unity入门
- unity入门
- unity入门
- Unity入门
- Ubuntu 双显配置问题。
- 关于专利的问题
- 使用PL/SQL Developer 远程连接Oracle数据库出现 “无监听程序“错误 的解决办法
- 技术问题分享之系统重装(未完待续...)
- Linux内核学习笔记: uid之ruid,euid,suid
- # Unity 引擎入门实践
- getPos
- Qmenu和Qaction
- G - Amusing Joke
- 专业游戏玩家如何选导热硅脂
- UIVIEW的各个属性详解
- JS识别不同浏览器信息
- Java 枚举(enum) 详解7种常见的用法
- Robot Framework自动化测试(一)---第一个脚本