Unity3D基础知识(一) MonoBehaviour脚本内置函数执行顺序测试

问题: 在Unity3D项目中经常会遇到不知道应该把初始化代码写在Awake(), Start()还是OnEnable()函数中.

测试: 直接上代码

using UnityEngine;

public class test_MonoBehaviour : MonoBehaviour
{
    public static string pressKey = string.Empty;
    void Awake()
    {
        Debug.Log("-----Awake-----" + pressKey);
    }
    void Start()
    {
        Debug.Log("-----Start-----" + pressKey);
    }

    void OnEnable()
    {
        Debug.Log("-----OnEnable-----" + pressKey);
    }
    void OnDisable()
    {
        Debug.Log("-----OnDisable-----" + pressKey);
    }
    void OnDestroy()
    {
        Debug.Log("-----OnDestroy-----" + pressKey);
    }
}
using UnityEngine;

public class test_MonoBehaviourCtrl : MonoBehaviour
{
    GameObject testDestroyObj;
    void Update()
    {
        if (Input.GetKeyUp(KeyCode.A))
        {
            test_MonoBehaviour.pressKey = "A";
            ///增加脚本相关测试///
            testDestroyObj = new GameObject("testDestroyObj");
            testDestroyObj.AddComponent();
            Debug.Log("-----AddComponent-----" + testDestroyObj);
        }
        else if (Input.GetKeyUp(KeyCode.S))
        {
            test_MonoBehaviour.pressKey = "S";
            ///Destroy删除相关测试///
            Destroy(testDestroyObj);
            Debug.Log("-----Destroy-----" + testDestroyObj);
        }
        else if (Input.GetKeyUp(KeyCode.D))
        {
            test_MonoBehaviour.pressKey = "D";
            ///DestroyImmediate删除相关测试///
            DestroyImmediate(testDestroyObj);
            Debug.Log("-----DestroyImmediate-----" + testDestroyObj);
        }
    }
}
当第一次按下"A"输出:
-----Awake-----A
-----OnEnable-----A
-----AddComponent-----testDestroyObj (UnityEngine.GameObject)
-----Start-----A
当按下"S"时输出:
-----OnDisable-----S
-----Destroy-----testDestroyObj (UnityEngine.GameObject)
-----OnDestroy-----S
当第二次按下"A"输出:
-----Awake-----A
-----OnEnable-----A
-----AddComponent-----testDestroyObj (UnityEngine.GameObject)
-----Start-----A
当按下"D"输出:
-----OnDisable-----D
-----OnDestroy-----D
-----DestroyImmediate-----null

总结:

1.  当加入一个脚本到GameObject上时, Awake和OnEnable会最先执行, 早于你函数体内的其他操作. 而Start则要晚一些. 

2. 需要在后续代码中用到的初始化内容, 必须写在Awake()函数中, 例如你的后续代码需要用到刚进去脚本的某些初始化设置, OnEnable()则是会每次激活都会进行调用. 一般用来做激活后初始化操作. 

4.  使用Destroy函数删除物件, 不能直接对物件进行 ~= null 等判断. 因为在同一帧之内, 这个物件并没有真正的删除.  这个要特别注意. 

5.  使用DestroyImmediate删除节点, 则是真正的删除, 后续代码使用 ~= null 的判断则能返回正确的值. 但是官方不建议使用此函数. 并且资源类型的物体, 是不可以使用此函数进行删除.

遗留问题:

怎么使用Destroy()删除物件, 并且能让后续代码不错误的访问该物件

你可能感兴趣的:(Unity3D)