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);
}
}
这是输出:
如您所见,它说了两次“Hello 3”。我想了解为什么会这样?我不知道我在哪里打了两次电话。在图像 2 中,您将看到只有 1 个房间实例(当我将房间类 C# 脚本附加到主摄像头时)。我没有将此脚本附加到任何其他内容。
最佳答案
这真是个好问题。在 Unity 中,当不继承自 MonoBehaviour 的对象的新实例在函数外时创建,
1。 Unity的脚本调用机制从Unity的主线程调用构造函数。
2。再次调用构造函数,但在 Unity 主线程之外从一个称为 MonoBehaviour
构造函数的地方调用。你can't甚至在进行第二次调用时在构造函数中使用 Unity 的 API,例如 GameObject.Find("Cube");
,因为它是从不同的线程进行的。
您可以通过使用以下代码输出每个函数调用的线程 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()
{
}
}
和
public class ClassB
{
public ClassB(int testNum)
{
Thread thread = Thread.CurrentThread;
Debug.Log("ClassB Constructor Thread ID: " + thread.ManagedThreadId); ;
GameObject.Find("ok");
}
}
解决方案:
从 Unity 的函数之一(例如 Awake
、Start
而不是 MonoBehaviour
构造函数中创建新实例。
public class Room : MonoBehaviour
{
public ClassB classBTestInstance;
// Use this for initialization
void Start()
{
classBTestInstance = new ClassB(3);
}
}
关于c# - 为什么在非 MonoBehaviour 类中调用多个构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45848998/