Unity 3D 游戏脚本 脚本的生命周期

Unity 3D 游戏脚本 脚本的生命周期_第1张图片

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

//--脚本绑定事件

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

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

using UnityEngine;

public class ScriptBindEventMyTools : MonoBehaviour
{
#if UNITY_EDITOR
    private void Reset()
    {
        Debug.Log("GameObject : " + gameObject.name + " bind script : ScriptBindEventMyTools");
    }
#endif
}

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

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

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

Unity 3D 游戏脚本 脚本的生命周期_第2张图片

using UnityEngine;

public class ScriptLifeFunction : MonoBehaviour
{
    private void Awake()
    {
        Debug.Log("Awake用于初始化并且永远只会执行一次");
    }

    private void OnEnable()
    {
        Debug.Log("OnEnable在脚本每次激活时都执行一次");
    }

    private void Start()
    {
        Debug.Log("Start在初始化的下一帧执行,并且永远只会执行一次");
    }

    private void FixedUpdate()
    {
        Debug.Log("FixedUpdate");
    }

    private void Update()
    {
        Debug.Log("Update");
    }

    private void LateUpdate()
    {
        Debug.Log("LateUpdate");
    }

    private void OnApplicationQuit()
    {
        Debug.Log("OnApplicationQuit应用退出时执行一次");
    }

    private void OnDisable()
    {
        Debug.Log("OnDisable每次脚本禁用时都执行一次");
    }

    private void OnDestroy()
    {
        Debug.Log("OnDestroy用于脚本销毁并且永远只会执行一次");
    }
}

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

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

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

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

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

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

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

Unity 3D 游戏脚本 脚本的生命周期_第3张图片

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

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

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

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

using System.Collections;
using UnityEngine;

public class CoroutineCreateCubeMyTools : MonoBehaviour
{
    private void Start()
    {
        StartCoroutine(CreateCube());
    }

    private IEnumerator CreateCube()
    {
        for (int i = 0; i < 10; i++)
        {
            GameObject.CreatePrimitive(PrimitiveType.Cube).transform.position = Vector3.one * i;
            yield return new WaitForSeconds(1.0f);
        }
    }
}

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

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

//--停止协程任务‘

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

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

using System.Collections;
using UnityEngine;

public class StopCoroutionMyTools : MonoBehaviour
{
    private IEnumerator CreateCube()
    {
        for (int i = 0; i < 10; i++)
        {
            GameObject.CreatePrimitive(PrimitiveType.Cube).transform.position = Vector3.one * i;
            yield return new WaitForSeconds(1.0f);
        }
    }

    private Coroutine m_Coroutine = null;

    private void OnGUI()
    {
        if (GUILayout.Button("StartCoroution"))
        {
            if (m_Coroutine != null)
            {
                StopCoroutine(m_Coroutine);
            }
            m_Coroutine = StartCoroutine(CreateCube());
        }
        if (GUILayout.Button("StopCoroution"))
        {
            if (m_Coroutine != null)
            {
                StopCoroutine(m_Coroutine);
            }
        }
    }
}

 

你可能感兴趣的:(Unity,3D,游戏开发,第二版,学习笔记)