Unity MonoBehaviour中的帧更新函数详解

本篇文章将详细讲解MonoBehaviour中的帧更新函数。

相信只要是在Unity中写过代码的人都知道Monobehaviour这个类。当你的脚本去继承这个Monobehaviour类并挂在在场景中的游戏物体上,那么当游戏运行时,则会执行这个类的一系列生命周期函数。

当游戏运行时,系统会自动的去收集场景中所有挂载在游戏物体上的脚本(也就是继承了Monobehaviour)。然后去调用他此时应该调用的生命周期函数,比如说,当游戏刚运行,系统会自动的去收集场景中所有Monobehaviour中的Awake函数进行调用,而哪个脚本的Awake函数先调用呢?这个先后顺序是不确定的,但是Awake的调用顺序,可以在unity中进行设置,而其他生命周期函数的执行先后顺序是未知的。当所有的Awake都执行完了,他才会继续去执行下一个生命周期函数。所以大家要明白一点,虽然有多个挂载在物体上的脚本,但实际上,他还是单线程的。而在真正开发的时候,我们会尽量去避免去继承这个Monobehaviour,因为他需要去收集所有物体的Monobehaviour,而从逻辑上来说,一个游戏其实只需要一个游戏入口进行驱动就可以了。不过具体还是看需求。

本篇文章的重点在于帧更新函数。Monobehaviour提供了三个帧更新函数。分别是Update,FixedUpdate,LateUpdate。大家用的最多的就是Update,在大家的印象中,可能Update中的内容就是每帧执行。那么FixedUpdate和LateUpdate呢?这两者也是每帧执行。那为什么我们一直都是用Update呢?如果大家去百度搜索这三者的区别,大多数情况会是这么一个答案:Update是执行间隔不固定,FixedUpdate固定间隔执行,LateUpdate是Update之后执行。

本质上这个说话没毛病,但是大家有没有想过,比如我们要写一个移动的代码,为什么我们经常看到的是写在Update里面而不是FixedUpdate中呢?FixedUpdate既然是固定间隔,那不是更准确吗?也许有的人会说,放FixedUpdate中也可以。那我们今天就来讲讲这三者到底是什么意思。

Update。是渲染帧执行。什么是渲染帧执行呢?比如我们看动画片,其实最早的动画片,他是通过把一个动作分解成很多长图片,并将图片连续播放,从而给我们看起来感觉像是真的动起来了。而一秒内播放了多少张图片,也就是我们常常说的多少帧。当一秒内播放的图越多,也就是帧数越高,那么这个动画看起来就会更逼真。而在我们的游戏中,我们的图像是通过计算机计算去渲染出来的,一秒内渲染几次画面,就是多少帧,所以帧数越高,游戏看起来就越流畅。而Update就是每次渲染画面的时候执行的。

FixedUpdate。是固定帧执行。顾名思义,每隔多久执行一次,那么这个间隔时间,是可以通过unity进行设置的。但是这个时间间隔也不是绝对的。极端情况下还是有可能会被影响的。

很多同学应该都在Update中写过这么一句代码。transform.position += transform.forward * Time.deltaTime。其实这句代码的含义,是去计算,下一帧渲染的时候这个物体的坐标。举个例子,我现在以每秒十米的速度向前奔跑,过了两秒,我应该在前方两米处,再过三秒,我应该在前方五米处。那么对应以上的代码,Time.deltaTime是每帧的间隔时间,而transform.forward是速度,那么速度乘以时间等于位移,可能之前大家会觉得上面的代码就是移动,但实际上他只是一直在更新自己的坐标位置。那么这时候问题来了,那我放在FixedUpdate里不是直接写transform.position += transform.forward就行了?因为这是固定间隔时间执行的。那为什么我要在Update中写而不在FixedUpdate中去写呢?

还是刚才的例子,如果说我以每秒十米的速度向前奔跑,由于Update间隔时间是不固定的,我们假设,他第二秒的时候执行一次,第五秒的时候执行一次,而FixedUpdate是固定间隔的,我们假设他每秒执行一次。那么就会导致,五秒内,FixedUpdate进行了五次计算,而Update只进行了两次计算,而我们上面说了,Update是渲染帧执行,也就是说当渲染画面的时候才会去执行,所以说,实际上我们玩家能看到的只有第二秒和第五秒的时候,而FixedUpdate剩下三秒的计算其实是没有任何意义的,所以会造成性能浪费。

还是刚才的命题,如果说在第四秒的时候,也就是前方四十米处有一个障碍物。那么这时候我们如果放在Update中计算就会导致玩家直接穿过去了,因为他只在渲染帧进行计算,而其他时候他是不管的,这时候就应该放在FixedUpdate中进行计算,无论有没有去渲染画面,都应该去计算。Update他只关心玩家所看到的,而FixedUpdate更注重过程。所以说,实际上,应该在Update还是在FixedUpdate中写代码,这个要看你具体的需求,也不需要去记什么物理就放FixedUpdate。其实通过我上面所讲的,你只要知道了什么是渲染帧执行,什么是固定帧执行就已经够了。

LateUpdate。在Update之后执行。上面已经说了,我们的生命周期函数,是场景中所有挂载脚本的物体的同一生命周期执行完,才会去执行下一个生命周期函数。所以说,LateUpdate是在所有的Update执行完之后才执行。也就是说,有可能你会有一些需求,有两件事情你都是要每帧去执行的,但是这两件事情一定要保证先后顺序,而上面我们说了除了Awake可以进行设置,其他生命周期函数的先后顺序都是未知的。所以这个LateUpdate就发挥作用了。

举个例子,角色身上有一个移动脚本,而摄像机上有一个跟随脚本,也就是摄像机要每帧都去通过角色的坐标来计算自己应该处在哪个坐标,那么这里我们通常会把摄像机的移动方法放在LateUpdate,让他始终在角色移动完才进行移动,因为如果摄像机先移动,那么可能会导致,出现摄像机看不到角色的bug,或者是抽搐。

那么这三个帧更新函数解释到这里就已经结束了,希望对大家有帮助。如果对大家有帮助,也希望大家多分享分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值