Unity技术笔记
之前也用过一段时间Unity,大概过了一年基本上都忘得差不多了,再加上之前不是很系统地对Unity进行学习,这次通过官方的教学和自己的实验结合来好好对Unity有个深入的理解和认识。
今天看了官方面向新手的最基本最基本的教学——Roll a Ball,内容是控制一个球去吃附近的小方块,吃完就算赢。
原教程的链接:https://unity3d.com/cn/learn/tutorials/projects/roll-ball-tutorial
游戏本身实现起来很简单,实现起来完全不用花费脑力。但是再简单的示例,也有几处我之前并不知道的东西,所以我还得学习一个...为了提高姿势水平,在这里把新学到的东西先给记下来了。
1. 三种Update()函数
教程中提到了三种Update()函数,分别是Update(),FixedUpdate(),LateUpdate()。以前我基本都是直接无脑用Update(),发现有东西实现不了就换成其他的,基本算是无的放矢,随便乱试,并没有去想三种Update本质上的区别。在教程中对这三类Update做了解释,是这样子的:
Update()函数是发生在每一帧渲染之前,FixedUpdate()函数是发生在每一次进行物理计算之前,LateUpdate()函数是发生在每一帧所有Item的处理结束之后。注意,Update和LateUpdate是每一帧,FixedUpdate是每一次。
稍微解释一下的话就是说,FixedUpdate()发生的时候,一切物理计算都还没有开始进行。物理计算是什么?就比如说Rigidbody.AddForce()这个给刚体加力的函数就是一个。事实上对于刚体的处理都是物理计算。那么FixedUpdate()的间隔是多少呢?Edit->Project Setting->time下的Fixed timestep中可以进行修改。比如设置成0.02的话就是每0.02秒进行一次物理计算,在进行物理计算之前运行FixedUpdate()中的代码。
这么说的话虽然理解了,但其实还是一脸懵逼,既然FixedUpdate()是固定时间更新,又是每一次更新都会重新进行一次物理计算,那我为什么还要用Update()这个函数呢?想想,游戏是实时渲染的,每一次要渲染出来展示给玩家看画面的时间间隔不是这个固定时间,而是我们所说的帧率。玩家只有在看到屏幕上的东西动了,才会知道这个东西真的动了吧(怎么感觉像说了句废话= =)。要是我所有处理都是放在FixedUpdate()里的话,那就会导致玩家真实看到的和游戏里正在发生的,虽然很小,但是会存在差距。举个栗子,有一个特别特别高端的动作类游戏玩家,能做到在敌人的武器离看到砍到自己还有0.00001秒的时候做出反应来回避,也就是能做到在没被砍到的那一帧和被砍到的那一帧之前做出回避反应,然而如果对玩家的伤害判定是放在FixedUpdate()里面,又恰巧在刚刚上述的两帧里进行了一次更新,而且物理计算后碰撞成立,这时候会造成的结果就是,这个高端玩家明明看到自己没有被砍到并进行闪避,但是结果是自己被砍到了。如果理解不了这个例子或者想吐槽说这个高端玩家实际上就是被砍到了,再读一下刚刚那句废话,玩家只有在看到屏幕上的东西动了,才会知道这个东西真的动了。
再说说实际上的操作,简单的来说,所有物理计算相关的都放在FixedUpdate中,所有游戏逻辑有关的都放在Update中。LateUpdate的话,现在除了移动相机之外暂时还想不出有啥应用,总之它是在渲染完成以后才会被调用的。
2. 关于Static Collider和Dynamic Collider
这是一个和优化有关的问题,先解释一下,我们一般希望把墙,房子,山这类不会动的物件作为Static Collider,而把车子,人之类的会动的作为Dynamic Collider。在Unity里,如果一个物体只有Collider但没有Rigidbody,那么Unity就会把这个物体认为是Static Collider。而如果两个都有的话就认为是Dynamic Collider。
然后是重点,这里涉及到Unity自身的优化问题。Unity 会把所有的它认为是Static Collider的物体在一开始进行计算并缓存成cache,这样之后如果没必要再进行计算了。而对于Dynamic Collider则是会每帧进行一次计算。容易出现的问题就是,如果Static Collider中,一旦有一个物体位置发生了改变,那么Unity会将所有的Static Collider重新进行一次计算并缓存。所以一旦有哪个会动的物体没有变成Dynamic Collider的话,它每一次移动都会让Unity重新把所有静态的东西全部再算一次,那就变成真·全部·实时渲染了。
然后解决办法当然是给那些不会动的东西加上刚体Rigidbody,但是会有一个随之而来的小问题,那就是一旦加上了刚体,这个东西就会收到各种物理因素影响而各种起飞,各种下落,就算把受重力影响勾掉也是没卵用的。这时候也很简单,如果你不希望这个物体真的受到物理影响,只要把IsKinamic的选项勾上就行了,Unity就会知道你只是想把它当做一个Dynamaic Collider来处理。
基本上这两个是比较重要的两点,其他的都是些比较基础的东西,不过也是很适合我来重温和热身的。之后打算写一个3D的贪吃蛇来练习一下作为实践,写完以后会更新这篇文章,或者再写一篇文章吧。