Aza*_*ias 3 c# constructor execution unity-game-engine inspector
我已经将一个脚本附加到Unity游戏对象.该脚本包含各种公共属性,包括我自己的一些类.如下面的简化代码所示,其中TestMonoBehaviorClass附加到游戏对象并且TestClass' TestString在检查器中显示.
public class TestMonoBehaviorClass : MonoBehaviour
{
public TestClass Test;
}
[System.Serializable]
public class TestClass
{
public string TestString;
public TestClass ()
{
Debug.Log ("TestClass creator called.");
this.TestString = "Reset String";
}
}
Run Code Online (Sandbox Code Playgroud)
当我将脚本附加到游戏对象时,我希望调用一次TestClass(编辑:不是从MonoBehavior派生的构造函数)的构造函数.但如果我在Unity编辑器中运行程序然后停止程序,则会调用它四次.如果我将脚本附加到两个游戏对象上,则会七次.至少我多次在控制台中看到Debug.Log的输出.
不过,如果我TestString在编辑器中更改属性的内容,我手动输入的内容不会被覆盖!
为什么构造函数经常调用?何时在Unity的执行顺序中调用(Unity的事件函数执行顺序)?我可以忽略调用,还是必须在构造函数中添加特殊处理?到目前为止,我没有看到任何实际问题或副作用.
编辑:似乎只调用没有参数的构造函数.如果我只有带参数的构造函数,则不调用任何构造函数.
[System.Serializable]这就是多次调用构造函数的原因.只要忽略它,除非因此而导致错误,然后询问有关解决方案的特定错误的问题.如果删除[System.Serializable],Unity将不会序列化TestClass类,构造函数将被调用一次而不是多次.
编辑:似乎只调用没有参数的构造函数.如果我只有带参数的构造函数,则不调用任何构造函数.
随着[System.Serializable],统一的序列化可以调用默认的构造函数多次系列化和脱盐过程中,因为它需要重新创建对象时其反序列化.构造函数用于执行此操作.有关Unity中其他类似的多个构造函数调用问题,请参阅此文章.
编辑:
如果要在序列化完成之前或之后执行操作,可以实现ISerializationCallbackReceiver接口并使用OnBeforeSerialize()或OnAfterDeserialize()函数分别执行此操作.
例如:
[System.Serializable]
public class TestClass : ISerializationCallbackReceiver
{
public string TestString;
public TestClass()
{
Thread thread = Thread.CurrentThread;
Debug.Log("TestClass creator called: " + thread.ManagedThreadId);
this.TestString = "Reset String";
}
public void OnAfterDeserialize()
{
Thread thread = Thread.CurrentThread;
Debug.LogWarning("OnAfterDeserialize Thread ID: " + thread.ManagedThreadId);
}
public void OnBeforeSerialize()
{
Thread thread = Thread.CurrentThread;
Debug.LogWarning("OnBeforeSerialize Thread ID: " + thread.ManagedThreadId);
}
}
Run Code Online (Sandbox Code Playgroud)