Unity 常用生命周期函数解析 - 超级详细,不服来辩
一,初始化
1.1 函数描述
运行状态初始化:(也是执行顺序)
Awake:初始化时调用,在 Start 函数之前调用
OnEnable:在对象启用时调用
Start:仅当启用脚本实例时,才会在第一帧调用
编辑器状态初始化:
Reset:编辑器下调用,当脚本第一次附加到物体上或者点击 Reset 时执行,来初始化脚本属性。
实际应用:
Awake:通常使用为需要提前初始化的逻辑。比如单例赋值
private void Awake(){Instance = this;}
。OnEnable:处理每次显示时都需要进行初始化的逻辑,通常和 OnDisable 配合使用。比如: 游戏逻辑使用并修改了变量
Number
,而下次显示时使用是又需要Number = 1
,此时就可以写private void Awake(){Number = 1;}
。Start:通常使用为一些变量初始化逻辑。比如:获取指定物体:
private void Start(){child1 = transform.GetChild(0);}
Reset:通常在游戏测试调试时,使用编辑器下的初始化。通过点击 Reset 执行一个逻辑。
1.2 示例解析
运行状态初始化示例: 搭建场景新建两个 UI -> Image,一个作为背景,一个作为弹窗。新建脚本并挂载到弹窗 Image 上。
脚本内容如下:
此次运行结果展示了Awake
,OnEnable
,Start
的执行顺序,运行结果:
编辑器下的初始化:1.脚本拖拽附加时自动执行
2.点击 Reset 调用: 可以看到我手动 Number 设置为 2,Reset 后被重置为代码中写的 0;
二,更新
2.1 函数描述
三个函数:
FixedUpdate:固定时间调用,FixedUpdate 通常比 Update 更频繁地调用
Update:每帧调用一次
LateUpdate:在 Update 完成后,每帧调用一次
实际应用:
FixedUpdate:所有物理计算和更新都在 FixedUpdate 中处理。它是固定时间调用,不会受到帧率影响。比如:一些物理属性的更新操作 Force,Collider,Rigidbody 等。
Update:每帧调用一次,根据帧率的快慢影响执行速度。通常的游戏逻辑都写在这里,比如:和玩家交换,当用户按下空格时进行执行什么操作。
LateUpdate:每次 Update 完成后调用移除。常见用处是相机跟随主角,比如:主角在 Update 中移动,则可以在 LateUpdate 执行相机的移动,这将可以保证摄像机跟着的时候之前的逻辑一起完全执行完成。
2.2 示例解析
将如下脚本添加到上面新建的脚本中:(为了方便查看,将上面初始化的函数先注释掉)
运行后,可以看到结果如下:
三,鼠标交互
3.1 函数描述
几个函数:
OnMouseEnter: 鼠标进入时调用一次
OnMouseOver: 鼠标停留(经过)时一直调用
OnMouseExit: 鼠标退出时调用一次
OnMouseDown: 鼠标按下时调用一次
OnMouseDrag: 鼠标拖拽(按住)时一直调用
OnMouseUp: 鼠标抬起时调用一次
<font size=3>实际使用:使用时一般都是成对使用
OnMouseEnter,OnMouseOver,OnMouseExit 一组。比如模拟选中状态:鼠标进入时物体变色,鼠标退出时再变回来。
OnMouseDown,OnMouseDrag,OnMouseUp 一组。比如射击游戏:鼠标按下拖拽时调整方向,抬起时发射子弹。
当鼠标按下并停留在当前游戏对象上时,OnMouseOver,OnMouseDrag 会同时触发。
<font size=3>检测原理:
只能检测当前脚本挂载的游戏对象。
当前游戏对象需要有碰撞体。
不能有其他物体(UI)遮挡到此游戏对象。
总结为一局话就是:OnMouseXXX 的原理是通过鼠标的射线检测来判断鼠标当前位置是否碰到了挂载脚本游戏对象的碰撞体。
勾选 IsTrigger:
若需要不检测勾选 IsTrigger 的碰撞体,Edit => Project Settings => Physics 中的 Queries Hit Triggers,将这个✅ 取消,即可不触发勾选 IsTrigger 的。【注意:默认是✅ 勾选状态,不需要触发则取消勾选】
3.2 示例解析
场景中创建一个 Cube,将其位置调整在摄像机先显示即可【示例中调整位置(0,0,-1),缩放为(3,3,3)】。
测试功能:
鼠标进入\退出,触发 Cube 颜色变化
鼠标移动到 Cube 上,触发旋转
鼠标在 Cube 按下并拖拽,触发 Cube 跟随移动
鼠标抬起 Cube 回归到原来位置
创建并挂载到 Cube 代码如下:
测试效果:
四,碰撞检测
4.1 函数描述
碰撞函数:
OnCollisionEnter: 进入碰撞时触发一次。
OnCollisionStay: 在碰撞体中停留时每帧触发一次。
OnCollisionExit: 离开碰撞体时触发一次。
触发函数:
OnTriggerEnter: 进入碰撞体时触发一次。
OnTriggerStay: 在碰撞体中停留时每帧触发一次。
OnTriggerExit: 离开碰撞体是触发一次。
PS:上面这六个方法,还有对应 2D 碰撞体的六个方法(如:OnCollisionEnter2D
) 函数后面添加 2D 接口,触发条件和使用方式和 3D 一致。 使用时注意碰撞体和检测函数同步接口,即用 2D 碰撞体必须用 2D 函数。
函数执行条件:
两个物体需要都有碰撞体(Collider)组件。
检测方(挂载脚本物体)需要有刚体(Rigidbody)组件。
Collider 上都不勾选 IsTrigger(有一方勾选则执行触发函数)。
4.2 示例解析
在三例上继续操作,在 Cube 上添加 Rigidbody 组件,并取消勾选 Use Gravity 属性(避免其受到重力影响)。
然后再创建两个 Cube,位置大小随意能在 Game 视图看到就行。将其中一个 BoxCollider 的 IsTrigger 属性勾选 ✅ 上。这样就可以一个用来测试碰撞,一个用来测试触发了。
将代码添加到OnMouseXXXTest
类中,添加内容如下:
运行后得到如下效果:
五,应用程序
5.1 函数描述
三个函数:
OnApplicationPause: 检测到暂停的帧结束 --> 切换到后台和回来时调用。
OnApplicationFocus: 当屏幕 获得/失去 焦点时调用
OnApplicationQuit: 当程序退出时调用。
实际应用:
OnApplicationPause: 游戏停止保存数据/游戏继续数据初始化。
OnApplicationFocus: 失去焦点关闭背景音乐/获得焦点继续播放音乐。
OnApplicationQuit: 在移动端大退时也会对调用,但不会触发上面两个方法。
5.2 示例解析
使用时将下面代码复制到需要处理检测逻辑的部分即可:
由下图可以看到执行逻辑:当我点击 Hierarchy 面板时触发失去焦点,再次点击 Game 视图则触发了获得焦点
六,禁用销毁
6.1 函数描述
三个函数:
OnDisable: 当对象被禁用时调用此函数(其父物体被禁用也会触发)。
OnDestroy: 在对象存在的最后一帧的所有帧更新之后调用此函数。
实际应用:
OnDisable: 通常和 OnEnable 配合使用。比如:在 OnEnable 添加监听,在 OnDisable 移除监听
OnDestroy: 当物体销毁或者场景关闭时触发。比如:子弹打到墙壁时,需要销毁子弹并触发一个打击音效。
6.2 示例解析
1.游戏物体禁用触发OnDisable
2.游戏物体销毁时触发OnDisable
和OnDestroy
Unity 官方图解:
怎么样?是不是收获颇丰。本文对你有帮助的话,欢迎小伙伴们三连支持一下。有问题的话我们评论见吧~
版权声明: 本文为 InfoQ 作者【陈言必行】的原创文章。
原文链接:【http://xie.infoq.cn/article/66c12630f02ca45d01fa7c10a】。未经作者许可,禁止转载。
评论