Day6-事件订阅、Unity生命周期
委托
delegate
学完之后我对delegate的理解是:一个限制了参数和返回值的函数指针
做个比喻的话,delegate就像一个火车头,规定了后续车厢的要求,只有符合要求的车厢才能接上火车头,而且不会拉空车
1 | public class Player : MonoBehaviour { |
无返回值、无传参(广播)
无返回值,无传参,几乎没有限制要求,所以可以挂载任意函数(任意车厢)
在这个使用场景下,用“广播”去做比喻更加合适
例如:玩家死亡时,显示游戏结束界面
1 | public class Player : MonoBehaviour { |
无返回值、有传参
使用场景例如:玩家掉血时,在玩家身边显示掉血数字
1 | public class Player : MonoBehaviour { |
有返回值
之前有提到,有返回值的delegate,只会返回最后挂载的函数的值,所以并不适合“广播”,这时候更倾向于他本身的翻译“委托”
1 | public class ShopSystem : MonoBehaviour { |
Action(封装无返回值的delegate)
Action是一个泛型委托,它可以表示没有返回值的方法。
1 | public class Player : MonoBehaviour { |
Func(封装有返回值的delegate)
Func是一个泛型委托,它可以表示有返回值的方法。
1 | public class ShopSystem : MonoBehaviour { |
Unity生命周期
Unity生命周期主要的有Awake、Start、Update、FixedUpdate、LateUpdate、OnEnable、OnDisable、OnDestroy
启动顺序
当物体勾选,开始渲染时,会按照以下顺序执行:
- Awake:始终在任何 Start 函数之前并在实例化预制件之后调用此函数。(如果游戏对象在启动期间处于非活动状态,也就是在Unity中未勾选,则在激活之后才会调用 Awake。)
- OnEnable:(仅在对象处于激活状态时调用,之前在GraphicsPanel中有应用)在启用对象后立即调用此函数。在创建 MonoBehaviour 实例时(例如加载关卡或实例化具有脚本组件的游戏对象时)会执行此调用。
- Start:仅当启用脚本实例后,才会在第一次帧更新之前调用 Start
- FixedUpdate:调用 FixedUpdate 的频度常常超过 Update。如果帧率很低,可以每帧调用该函数多次;如果帧率很高,可能在帧之间完全不调用该函数。在 FixedUpdate 之后将立即进行所有物理计算和更新。在 FixedUpdate 内应用运动计算时,无需将值乘以 Time.deltaTime。这是因为 FixedUpdate 的调用基于可靠的计时器(独立于帧率)。
- Update:每帧调用一次 Update。这是用于帧更新的主要函数。
- LateUpdate:每帧调用一次 LateUpdate__(在 Update__ 完成后)。LateUpdate 开始时,在 Update 中执行的所有计算便已完成。LateUpdate 的常见用途是跟随第三人称摄像机。如果在 Update 内让角色移动和转向,可以在 LateUpdate 中执行所有摄像机移动和旋转计算。这样可以确保角色在摄像机跟踪其位置之前已完全移动。
- 动画更新循环(暂不需要深究)
- 渲染Rendering(暂不需要深究)
- OnDisable:行为被禁用或处于非活动状态时,调用此函数(往往和OnEnable配对使用)
- OnDestroy:对象存在的最后一帧完成所有帧更新之后,调用此函数
- OnApplicationQuit:在退出应用程序之前在所有游戏对象上调用此函数。在编辑器中,用户停止播放模式时,调用函数
一些注意事项
- Start永远运行在所有Awake之后运行,所以在Awake当中获取当前物体组件(GetComponent),在Start中跨物体交互,
- Awake与Start只会运行一次,而OnEnable和OnDisable会根据对象的状态变化而运行多次(所以刷新UI的内容要写在OnEnable中,先前GraphicsPanel中下拉选项的更新就是如此)
- SetActive(false)不是销毁物体,再次启用不会运行Awake和Start,所以这是节省性能的一个途径,例如UI的隐藏,子弹模型的复用
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Petrichor' Blog!
评论