漫话Unity(二)

三、Unity编辑器介绍

Unity是一个商业级的3d游戏引擎。一个引擎的专业程度其实并不是体现在它多么牛b 的次世代效果,说实话那些效果即便你会用也不敢用,因为没有哪个手机是次世代的。游戏引擎的专业程度体现在两个方面,一是编辑器的完善程度,二是基础设施的完善程度和优化程度(比如说异步资源加载,文件打包系统,场景管理效率,裁剪性能,渲染优化,性能分析等等)。毫无疑问Unity在这些方面都是非常优秀的。除了写代码,你可以使用自己习惯的编辑器外,其他的东西都可以在Unity提供的一个大一统的编辑器下完成。包括场景编辑,游戏调试,资源管理,动画编辑等等。甚至你还可以轻易的扩展编辑器的功能,让它提供诸如关卡编辑、怪物编辑、技能编辑等等功能。

这个就是Unity的编辑器了。最上面是一行菜单,菜单可以轻易的通过代码来扩展。

第一部分是场景物件浏览窗口,所有的场景物件都会在这里显示出来,如果运行了游戏,那么动态创建的物件也会在这里显示出来。你可以点击其中的一个物件来查看和修改它的属性。

第二部分是游戏运行窗口,可以查看游戏运行结果,游戏运行的时候也可以切换到scene分页查看当前场景,在场景视口中可以操作场景摄像机和场景物件。

第三部分是物件属性窗口,可以查看当前选定物件或者资源的属性。每个物件必然都有Transform属性,控制物件的大小、旋转、缩放,这里的属性修改可以直接反馈到运行的游戏中,但是要注意,运行时的属性修改不会保存,停止运行后属性会还原。

第四部分是资源窗口,它显示的是当前Assets目录下的实际文件夹和文件。这里需要注意两点,点击这里然后修改属性对应的是文件修改,不存在游戏运行与否的区别。移动文件尽量在Unity内部进行,这样材质和脚本等会被正确的关联,但是如果是在windows浏览器下修改的,那么很有可能这些关联就都丢失了,你就不得不重新绑定或者设置。

四、Unity的开发语言

Unity的开发语言是C#,当然如果你非常熟悉javascript或者非常不喜欢c#,你也可以选择使用js来进行开发。在我看来js除了个人语言习惯外并没有其他优势,为了提高运行效率,Unity中的js并不是纯正的js,而是经过修改的(貌似是微软干的),而且js是编译成dll之后才加载运行的,这意味着不可能像cocos2d-x中的js一样,当作纯脚本动态的更新并加载。

C#原本是微软的.Net官方语言,是windows独有的。而开源界的大神们开启了一个名叫Mono的项目,用于把C#移植到Linux等非windows平台。而Unity正是基于Mono项目,使得其具备非凡的跨平台移植能力。

Unity执行C#的原理是先编译成dll(无论是哪个平台都是dll,这个动态库并不是程序直接加载的那种动态库,而是由Mono库来加载执行的),然后加载执行。这意味着你不能更新代码的内容(细节会在后面讨论自动更新的时候再说),因为代码文件已经包含程序包内了,但是在不更新代码内容的前提下,一个预制(Prefab,后面会介绍)中绑定哪个脚本以及脚本开放的参数配置都是可以随意更新的。

五、Unity的基本元素

Unity场景中的所有物件都是GameObject。GameObject是一个物件(如一个箱子,或者一个怪物),同时它也是一个节点,比如你可以创建一个空的GameObject然后把所有的怪物都挂接在这个节点下。场景物件窗口可以直接看到所有物件的层级关系。

每个GameObject都可以添加任意的Component,组件是Unity中另一个核心的基本要素。可以说万事万物皆组件,Unity中写代码的过程就是创建脚本作为组件挂接到GameObject上面来操作其属性的过程。你只能创建一个GameObject而不能通过继承来扩展它,但是你可以通过组件来任意的扩展它的功能,这就是基于组件的编程模式。习惯之后就会发现它的灵活和强大之处。

GameObject有一个必备的组件就是Transform,它描述了物件的旋转、偏移、缩放,在属性窗口中显示的都是相对于父节点的数值,如果你在代码中直接设置transform.position,Unity会自动把这个绝对坐标修改为相对于父节点的坐标。

其他一些常用的系统组件介绍:

Mesh Render、Skin Mesh Render模型都会有这个组件,负责模型的显示。可以说只要能够显示的东西,无论是复杂的人物模型,还是简单的几何体,或者纯粹是一个图片,都会有Mesh Render这个组件。

Material组件,材质跟Shader关联在一起,Mesh Render中选择依赖的材质,材质中选择使用的Shader,shader中选择对应的纹理。这几样东西配合起来就组成了一个可渲染的物体。

Collider组件,碰撞盒(Box Collider),模型碰撞体(Mesh Collider)等都是属于这个组件。要想发生碰撞必然要设置这个组件。

RigidBody组件,刚体组件,控制一个物体的质量、阻力等等。要想发生碰撞,碰撞的双方一定要有一个物体是具备刚体组件的。

Charactor Controller组件,这个比较特别,它与刚体组件等价,用于模拟rpg或者fps中的主角的物理运动效果,可以发生碰撞,但是不受真实物理影响。

Animator组件,控制人物动画播放。

Unity中最常用的系统组件就这些,剩下的还有一些是特殊物体特有的,比如摄像机控制、灯光、地形等等。

六、Unity脚本开发之函数

Unity很聪明的选择了C#来作为脚本,可以在保证效率的基础上降低了开发门槛。 C#具备三个非常优秀的品质,垃圾收集、完善的基础库和反射机制,这些是c++很难具备的(不是说c++就不具备,只不过实现并推广基于c++的垃圾收集和反射并不是一件多么容易的事情,像boost十多年了也没有真正普及)。

所有的脚本都是继承自MonoBehaviour,而MonoBehaviour则继承自Component,它就是一个组件。你可以随意创建脚本,然后把它挂接到GameObject,然后脚本就会被执行。MonoBehaviour提供了很多基础的功能,熟悉这些功能后Unity的脚本开发就不在话下了。

Awake  Start   Destroy   OnEnable   OnDisable   Update  OnGUI,这几个是最常用的函数,你只要在脚本中创建这么一个函数,那它就会在合适的时机调用。 调用的方式是基于反射的,并不是基于虚函数。所以函数是否是public,返回值是什么都无关紧要。但是要注意,如果是自己写的基于虚函数的override的话,就要在基类里面声明函数为virtual,子类里面声明为override,如果忘记写,编译器不会报错,但是执行不到正确的代码。

Awake是在刚绑定好脚本的时候(多数情况下就是GameObject被实例化好的时候)调用,这个时候所有的开放给编辑器配置参数都会初始化好,是脚本最先被执行的代码。

Start是物体在第一帧被渲染的时候调用,有时候你会实例化一个物体,然后再在代码中设置一些参数,而依赖于这种操作的代码都可以放到Start里面。

Update是每一帧都会被调用的函数。与之类似的还有FixedUpdate,这个函数是固定间隔调用,时间快慢、帧率快慢、是否在后台都没有关系。基本上可以这么认为除了物理模拟等特殊情况,否则能不用FixedUpdate就不用,能不写Update就不要再脚本中保留这个函数。

OnGUI是绘制Unity的UI的时候调用的,一般这个函数没什么用。除了测试的时候方便些(如随意两行代码写一个button,然后点击后触发一个测试的效果),无论从便捷性还是效率上都被那些GUI插件甩了几条街。

这里在额外提两个函数OnCollisionEnter和OnTriggerEnter,这两个是碰撞检测相关的。如果物体上有碰撞盒那么就会调用该物体绑定脚本中的这个函数。如果Collider勾选了IsTrigger选项,那么碰撞和不会发生碰撞位移,纯粹是作为触发器,调用的是Trigger系列的函数。否则调用的是Collision系列的函数。  每个系列都有Enter Stay Exist三个函数分别对应物体刚发生碰撞,持续碰撞中,物体分离的情况。

七、Unity脚本开发之属性与消息传递

每个组件(其实就是脚本内部),都有一些列属性可以方便的获取到我们想要的对象。属性内有gameObject、transform、rigidbody、collider、audio、render等属性。最常用的而且也是必然有的是gameObject和transform,它就是这个脚本所挂接的物体。如果这个物体上面同时还有刚体或者碰撞盒或者添加了声音组件,那么直接rigidbody等系统默认提供好的属性就可以用了。当然,你也可以手工在代码中使用GetComponent<要查找的类名>()来获取组件。

gameObject中有transform和rigidbody等属性,transform和rigidbody中同样有gameObject属性,这些引用关系可以方便的通过任意对象查找到你需要的东西。

你可以直接使用GameObject.Find("对象名字")来查找一个物体,其中对象名字可以包含层级路径。gameObject也可以使用GetComponent或者GetComponentInChildren来在当前或者子节点中获取对应的脚本。相关的函数非常丰富,你可以根据对象类型或者是Tag标签名等等来获取一个或者多个物体。

脚本内部可以使用Invoke("函数名", 延迟时间)来异步调用一个当前脚本内部的函数,或者使用SendMessage("函数名",参数)来调用一个函数,SendMessage非常方便的一点是它可以由gameObject来调用,只要你获得了一个物体,就可以使用SendMessage来调用一个函数,只要这个物体绑定的脚本中有一个同名函数,那么就会被调用。当然灵活也是有代价的,无论是Invoke还是SendMessage都比实际函数调用或者是委托(delegate)要低效很多,所以不要滥用(比如在Update中使用)。

熟悉了这几个知识点,那么你就可以写出符合Unity风格的代码了。剩下的都是对基础数学、算法、图形学、设计模式的理解了,这些知识是与引擎无关的,你拿Ogre能写出来,Unity也可以轻松的实现。

(第二部分在这里告一段落,它描述了Unity开发到底是怎么回事,虽然基础,但是是经过一段时间的代码积累才总结出来的,作为入门,它更加直面本质。我一直以为,会学习的人和不会学习的人差别就在总结和对本质的把握上面。会学习的人可以把握事物的本质,能够总结出这些东西究竟有哪几个知识点,原理是什么,原因是什么;而不会学习的人只会照猫画虎,能实现功能但是不得要领,知其然而不知道其所以然)

漫话Unity(二)

时间: 2024-10-09 09:25:00

漫话Unity(二)的相关文章

GVR SDK for Unity(二)

前言 关于google vr sdk的具体使用,传送门 [Gvr]Google VR SDK for Unity(一) Google Daydream平台已经整合进Google VR SDK 本文环境:Unity5.3.1 x64 , Gvr SDK 0.8 , VS2013 单词翻译 stereo:立体的: pose:姿势: gaze:凝视,注视:Reticle:十字线,准星 :Responder:应答者: provider:提供者:ProviderFactory:工厂类: Emulator:

Unity (二) Animator:Events : 动画事件案例(呐喊出现字幕)

Events的运用案例1: 在呐喊动画中,加入字幕事件 1)在呐喊动画Shout里添加2个事件: 2)在画布里添加一个Text作为字幕 将Text设为不激活 3)给角色添加脚本: 把画布里的Text拖给脚本的text 在脚本里声明动画里的2个事件方法 注意:      * 事件必须是放置在该人物对象的脚本组件中 * 添加了帧事件,必须在代码里声明时间方法,否者报错, * 函数必须是public权限的 * 参数只能增加一个,参数类型只能是Float,Int,String.Object之一, Sho

深入理解IOC模式及Unity框架

学习IOC发现如下博客写的很清楚了,故Mark下来以便以后查阅和温习! 1.IoC模式:http://www.cnblogs.com/qqlin/archive/2012/10/09/2707075.html  这篇博客是通过一个播放器的例子来说明什么是依赖,依赖倒置,控制反转(IOC),最后实现依赖注入.通过Unity实现IOC容器.不错的一个例子 2.深入理解DIP.IoC.DI以及IoC容器 这个算是最通俗易懂的,手动实现了IOC容器  由浅入深 3.理解依赖注入(IOC)和学习Unity

Unity轻量级依赖注入容器

一.前言 Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.在Nuget里安装unity 二.Unity的API方法 UnityContainer.RegisterType<ITFrom,TTO>();  //注册映射 UnityContainer.RegisterType< ITFrom, TTO >("keyName");//注册映射指定key值 IEnumerable<T> databases = UnityCon

IOC模式及Unity框架文章收藏

1.IoC模式:http://www.cnblogs.com/qqlin/archive/2012/10/09/2707075.html 通过Unity实现IOC容器. 2.深入理解DIP.IoC.DI以及IoC容器 3.理解依赖注入(IOC)和学习Unity 4.你真的了解Ioc与AOP吗? 5.[调侃]IOC前世今生 6.Unity系列 Unity(一):从ObjectBuilder说起 Unity(二):Unity是什么? Unity(三):快速入门 Unity(四):使用场景Ⅰ:建立类型

Unity5 GI与PBS渲染从用法到着色代码

本文主要介绍Untiy5以后的GI,PBS,以及光源探头,反射探头的用法以及在着色器代码中如何发挥作用,GI是如何影响渲染的,主要分成三个部分,最开始说明PBS需要的材质与相应概念,二是Unity 里相应GI的操作,三是对应着色器代码的理解.如果没有特殊声明,所有操作与代码都是针对Unity5.3. PBS材质与概念 简单来说,PBS的优点不同的照明下获得一致的外观,更容易实现,更直观的参数. PBS材质概念: 1.albedo 反照率 反照率贴图定义漫反射的基本颜色,与原来的漫反射贴图相比,不

Unity里面的自动寻路(二)

接着我的 上一篇自动寻路文章,这一次我们就来学习一下与自动寻路有关的组件吧.Unity中与自动寻路相关的组件主要有两个:NavMeshAgent (  又称导航网格代理 ),Off Mesh Link( 分离网格链接 ).这两个组件的作用与使用范围是不同的,我们唯一可以确定的是我们必须烘焙地形,产生NavMesh(导航网格).因为导航网格决定我们的角色(带有导航网格代理的角色)活动的范围.NavMeshAgent组件需要附着寻路的角色身上,比如怪物,而OffMeshLink这个组件主要是用来构造

【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&amp;颜色、光照与材质

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 本篇文章中,我们学习了Unity Shader的基本写法框架,以及学习了Shader中Properties(属性)的详细写法,光照.材质与颜色的具体写法.写了6个Shader作为本文S

【Unity 3D】学习笔记二十八:unity工具类

unity为开发者提供了很多方便开发的工具,他们都是由系统封装的一些功能和方法.比如说:实现时间的time类,获取随机数的Random.Range( )方法等等. 时间类 time类,主要用来获取当前的系统时间. using UnityEngine; using System.Collections; public class Script_04_13 : MonoBehaviour { void OnGUI() { GUILayout.Label("当前游戏时间:" + Time.t