U1L2——生命周期函数
U1L2——生命周期函数
本章代码关键字
1 | MonoBehaviour //脚本内继承该类且脚本与继承该类的类名一致才能使脚本挂载到一些对象上,注意这种类不能new出来,也不再建议写构造函数 |
生命周期函数的概念
所有继承 MonoBehaviour 的脚本(类) 最终都会挂载到 GameObject 游戏对象上。
生命周期函数 就是该脚本对象依附的 GameObject 对象从出生到消亡的整个生命周期中,会通过反射自动调用的一些特殊函数。
Unity 帮助我们记录了应该 GameObject 对象依附了哪些脚本,会自动的得到这些对象,通过反射去执行一些固定名字的函数。
Unity 中所有对象上挂载的生命周期函数都是在一个主线程中按先后执行的
Unity 会主动把场景上的对象,对象上挂载的脚本都统统记录下来,
在主线程的死循环中,按顺序按时机的通过反射,执行记录的对象身上挂载的脚本的对应生命周期函数
注意!
生命周期函数的访问修饰符一般为
private 和protected
因为不需要在外部调用生命周期函数 都是 Unity 自己帮我们调用的当对象(自己这个类的对象,也就是脚本)被创建时 才会调用该生命周期函数
接下来所说的生成,激活,失活,销毁,是相对于挂载到 Unity 对象上的脚本对象说的
类似于构造函数的存在 我们可以在一个类对象 刚创建时进行一些初始化操作这些生命周期函数 如果我们不打算在其中写逻辑 那就不需要再写出该生命周期函数!(因为脚本由反射得到代码执行,多余的生命周期函数会有性能上的开销)
这些脚本可以挂载到任意的对象上,但是不同的对象挂载相同的脚本 实例化的是不同的对象,这是各管各而不是共享的!
哪怕是一个对象挂载了重复的同一个脚本,也是实例化出不同的对象
切记!!继承
MonoBehaviour 的脚本不要new,不要new,不要new!!
生命周期函数
生命周期函数按照执行顺序依次有:
1 | Awake() { } //当一个对象被创建了,awake()会立刻执行 |
Awake()
当对象(自己这个类的对象,也就是脚本)被创建时 才会调用该生命周期函数
接下来所说的生成,激活,失活,销毁,是相对于挂载到unity对象上的脚本对象说的
类似于构造函数的存在 我们可以在一个类对象 刚创建时进行一些初始化操作
1 | protected virtual void Awake() |
OnEnable()
想要当一个对象被激活(从失活恢复到激活状态也会触发)的时候,进行一些逻辑处理,就可以写这个函数
1 | void OnEnable() |
Start()
与awake()一样,都是对象在被创建出来后只会调用一次的函数,但是,两者仍有区别,区别在于两者的执行时机不同
例如,如果在帧更新时,一个对象被创建了,awake()会立刻执行,而start()则会在本帧循环结束后,下一帧开始前执行,
也就是该对象第一次帧更新之前执行
1 | void Start() |
FixedUpdate()
这个主要用于 进行物理更新,它是每一帧的执行的 但是 这里的物理帧 和 游戏帧 有点不同
它的时间间隔 是可以在Project Setting中的Time里去设置的

1 | void FixedUpdate() |
Update()
主要用于处理游戏核心逻辑更新的函数
1 | void Update() |
LateUpdate()
一般这个更新是用来处理 摄像机位置更新相关内容的
Update 和 LateUpdate之间,Unity进行了一些处理 处理动画相关的更新
1 | void LateUpdate() |
OnDisable()
如果我们希望在一个对象每次失活时做一些处理 就可以在该函数中写逻辑
1 | void OnDisable() |
OnDestroy()
对象被销毁时调用 依附的GameObject对象被删除时(该组件被移除也会调用,只会调用一次)
1 | void OnDestroy() |
此外、还有碰撞检测函数、OnGUI()等这种特殊的生命周期函数
生命周期函数支持多态
类可以继承,且遵循多态,可以vob重写
1 | public class Lesson1 : MonoBehaviour |
1 | public class Lesson1Son : Lesson1 |
关于 MonoBehaviour 的类中的构造函数
我们要知道,虽然建议大家不在继承 MonoBehaviour 的类中写构造函数
但是不意味着我们不能写,当我们在继承 MonoBehaviour 的类中写无参构造函数时,
你会发现在编辑模式下或者运行后,只要该脚本挂载在场景中,那么该无参构造函数是会被自动执行的。
因为 Unity 的工作原理中提到的反射机制,Unity实际上通过反射帮助我们实例化了该脚本对象,既然要实例化那么肯定是需要 new 的,
只不过 Unity 中不需要我们自己 new 继承了 MonoBehaviour 的类,只要挂载后 Unity 帮助我们做了这件事。
那么为什么不建议大家写构造函数呢?
- Unity 的规则就是,继承
MonoBehaviour 的脚本不能new只能挂载 - 生命周期函数的
Awake是类似构造函数的存在,当对象出生就会自动调用 - 写构造函数反而在结构上会破坏Unity设计上的规范
总结:
如果继承 MonoBehaviour 的脚本想要进行初始化相关,可以在 Awake 或者 Start 中进行,
搞清这两个生命周期函数的执行时机,根据需求选择在哪里进行初始化。
切记!!继承
MonoBehaviour 的脚本不要new,不要new,不要new!!
不同脚本间生命周期函数的执行顺序
场景中不同脚本中的相同生命周期函数的执行时机是不确定的,
这导致当两个脚本相互依赖时,比如 A 依赖 B 中的初始化数据,我们一定要保证 A 在使用 B 数据时,B 已经被初始化了
如果要指定某些脚本生命周期函数执行的优先级,可以在 Project Setting 内的 Script Execution Order 内进行配置
点击 C# 脚本的 Inspector 面板的 Execution Order... 按钮可以直接打开对应窗口

将脚本添加到自定义订单中,并拖动它们以重新排序。
自定义顺序中的脚本可以在默认时间之前或之后执行,并且是自上而下执行的。
所有其他脚本则按照加载顺序在默认时间执行。(更改脚本的顺序可能会修改多个脚本的.meta元数据。)

