为什么在非MonoBehaviour类中进行多个构造函数调用?

The*_*mer 2 c# unity-game-engine

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Room : MonoBehaviour {

    public ClassB classBTestInstance = new ClassB(3);

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

public class ClassB {
    public ClassB(int testNum) {
        Debug.Log("hello " + testNum);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

在此输入图像描述

你可以看到它说"Hello 3"两次.我希望了解为什么会出现这种情况?我没看到我把它叫了两次.在image2中,您将看到只有一个房间实例(当我将房间类C#脚本附加到主摄像机时).我没有将此脚本附加到其他任何内容上.

在此输入图像描述

Pro*_*mer 12

这真是一个很好的问题.在Unity中,当在函数外部创建不从MonoBehaviour继承的Object的新实例时,

1.Unity的脚本调用机制从Unity的主线程调用构造函数.

2.再次调用构造函数,但在Unity主线程外部从一个称为构造函数的位置调用MonoBehaviour.你甚至不能使用Unity的API,例如GameObject.Find("Cube");在构造函数中进行第二次调用时,因为它来自不同的Thread.


您可以通过以下代码输出每个函数调用的Thread ID来了解更多信息:

public class Room : MonoBehaviour
{

    public ClassB classBTestInstance = new ClassB(3);

    // Use this for initialization
    void Start()
    {
        Thread thread = Thread.CurrentThread;
        Debug.Log("Room (MainThread) Thread ID: " + thread.ManagedThreadId);
    }

    // Update is called once per frame
    void Update()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

public class ClassB
{
    public ClassB(int testNum)
    {
        Thread thread = Thread.CurrentThread;
        Debug.Log("ClassB Constructor Thread ID: " + thread.ManagedThreadId); ;

        GameObject.Find("ok");
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方案:

从Unity的一个函数内部创建新实例Awake,Start而不是MonoBehaviour构造函数.

public class Room : MonoBehaviour
{

    public ClassB classBTestInstance;

    // Use this for initialization
    void Start()
    {
        classBTestInstance = new ClassB(3);
    }
}
Run Code Online (Sandbox Code Playgroud)