当前位置:   article > 正文

Unity 3D 游戏脚本 脚本的生命周期_unity debug.log只执行了一次

unity debug.log只执行了一次

生命周期中的所有方法都是Unity 系统自己回调的,不需要手动调用。

//--脚本绑定事件

在编辑器模式下,把脚本拖拽到一个游戏对象上,即为绑定。

Unity 并没有提供脚本的绑定事件,但是我们可以通过生命周期中的Reset()方法来实现。

  1. using UnityEngine;
  2. public class ScriptBindEventMyTools : MonoBehaviour
  3. {
  4. #if UNITY_EDITOR
  5. private void Reset()
  6. {
  7. Debug.Log("GameObject : " + gameObject.name + " bind script : ScriptBindEventMyTools");
  8. }
  9. #endif
  10. }

//--脚本初始化和销毁

脚本挂在游戏对象上,运行时就会立即执行初始化方法 Awake() ,它是一个同步方法,而 Start() 方法会在下一帧执行。如果游戏对象被删除,或者挂在它身上的脚本被删除,就会执行 OnDestroy() 方法。初始化或销毁在脚本的生命周期中只会执行一次。

游戏对象还有个状态,叫禁用状态。在程序运行中,可以多次设置激活/禁用,同时系统会分别调用生命周期中的 OnEnable() 和 OnDisable() 方法(反复激活/禁用,方法会反复调用,即方法在生命周期中可能会执行多次)。

  1. using UnityEngine;
  2. public class ScriptLifeFunction : MonoBehaviour
  3. {
  4. private void Awake()
  5. {
  6. Debug.Log("Awake用于初始化并且永远只会执行一次");
  7. }
  8. private void OnEnable()
  9. {
  10. Debug.Log("OnEnable在脚本每次激活时都执行一次");
  11. }
  12. private void Start()
  13. {
  14. Debug.Log("Start在初始化的下一帧执行,并且永远只会执行一次");
  15. }
  16. private void FixedUpdate()
  17. {
  18. Debug.Log("FixedUpdate");
  19. }
  20. private void Update()
  21. {
  22. Debug.Log("Update");
  23. }
  24. private void LateUpdate()
  25. {
  26. Debug.Log("LateUpdate");
  27. }
  28. private void OnApplicationQuit()
  29. {
  30. Debug.Log("OnApplicationQuit应用退出时执行一次");
  31. }
  32. private void OnDisable()
  33. {
  34. Debug.Log("OnDisable每次脚本禁用时都执行一次");
  35. }
  36. private void OnDestroy()
  37. {
  38. Debug.Log("OnDestroy用于脚本销毁并且永远只会执行一次");
  39. }
  40. }

//------------------

//--脚本更新与协程任务

在脚本整个生命周期中,主要提供了如下3中更新方法。

1.Update() :每一帧执行时,就会立即调用此方法。

2.LateUpdate():Update()方法执行后,都会调用此方法。

3.FixedUpdate() : 固定更新。默认情况下,系统没0.02秒调用一次,具体的间隔时间可以才TimeManager 中配置。

在Editor→ProjectSetting→Time ,即可打开TimeManager。

Update()  和 LateUpdate() 属于立即更新,更新之间的频率是不固定的,比如某一帧有一个耗时操作时,就会影响到下一帧更新的时间,所以对更新频率要求比较稳定的物理系统就不适合在这里处理更新。

FixedUpdate()  虽然是固定更新,但是其实也是相对固定,比如某帧耗了好几秒,它依然会卡住。正常程序会优化耗时操作,小范围帧率波动是正常的,可以让它更新的时间间隔稍微长一些,这样它的更新是比较平滑的。开发中例如以秒为单位的倒计时,并不需要每一帧去判断时间,所以用FixedUpdate() 比较合适。

Unity 的脚本只支持单线程,不过它引入了 C# 语言协程的概念,可以用来模拟多线程而不是真正的多线程。

例如每等一秒创建一个游戏对象,在Update中实现比较复杂,利用协程就简单了。

  1. using System.Collections;
  2. using UnityEngine;
  3. public class CoroutineCreateCubeMyTools : MonoBehaviour
  4. {
  5. private void Start()
  6. {
  7. StartCoroutine(CreateCube());
  8. }
  9. private IEnumerator CreateCube()
  10. {
  11. for (int i = 0; i < 10; i++)
  12. {
  13. GameObject.CreatePrimitive(PrimitiveType.Cube).transform.position = Vector3.one * i;
  14. yield return new WaitForSeconds(1.0f);
  15. }
  16. }
  17. }

协程可以让代码写起来更简化,但是很容易出错。不建议大量使用协程程序。

//-------------------------------

//--停止协程任务‘

在协程任务启动的过程中,如果需要从新启动它,必须停掉之前的协程。每次启动协程时,StartCoroutine() 将返回这个协程对象,需要停止的时候使用StopCoroutine() 传入对象即可。

也可调用 StopAllCoroutions() 停止这个脚本所启动的所有协程任务。

  1. using System.Collections;
  2. using UnityEngine;
  3. public class StopCoroutionMyTools : MonoBehaviour
  4. {
  5. private IEnumerator CreateCube()
  6. {
  7. for (int i = 0; i < 10; i++)
  8. {
  9. GameObject.CreatePrimitive(PrimitiveType.Cube).transform.position = Vector3.one * i;
  10. yield return new WaitForSeconds(1.0f);
  11. }
  12. }
  13. private Coroutine m_Coroutine = null;
  14. private void OnGUI()
  15. {
  16. if (GUILayout.Button("StartCoroution"))
  17. {
  18. if (m_Coroutine != null)
  19. {
  20. StopCoroutine(m_Coroutine);
  21. }
  22. m_Coroutine = StartCoroutine(CreateCube());
  23. }
  24. if (GUILayout.Button("StopCoroution"))
  25. {
  26. if (m_Coroutine != null)
  27. {
  28. StopCoroutine(m_Coroutine);
  29. }
  30. }
  31. }
  32. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/94414
推荐阅读
相关标签
  

闽ICP备14008679号