为什么在非MonoBehaviour类中有多个构造函数调用? [英] Why multiple constructor calls in a non MonoBehaviour class?
问题描述
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".我想了解为什么会是这种情况?我看不到我两次叫过它的地方.在image2中,您将看到只有一个房间实例(当我将房间类C#脚本附加到主摄像头时).我没有将此脚本附加到其他任何内容上.
As you can see that it says "Hello 3" twice. I wish to understand why might that be the case? I don't see where I called it twice. In image2 you will see that there is only 1 instance of room (when i attached the room class C# script to the main camera). I didn't attach this script to anything else.
推荐答案
这确实是一个好问题.在Unity中,当函数外部创建了不继承自MonoBehaviour的Object的新实例时,
This is really a good question. In Unity when new instance of an Object that does not inherit from MonoBehaviour is created outside a function,
1 .构造函数是通过Unity的脚本调用机制从Unity的主线程中调用的.
1. The constructor is called from Unity's main Thread by Unity's script calling mechanism.
2 .再次调用该构造函数,但在Unity主线程之外从称为MonoBehaviour
构造函数的位置调用该构造函数.您 不能 甚至在构造函数中使用Unity的API,例如GameObject.Find("Cube");
,因为第二次调用是由不同的线程进行的.
2. The constructor is called again but outside the Unity main Thread from a place known as the MonoBehaviour
constructor. You can't even use Unity's API such as GameObject.Find("Cube");
in the constructor when that second call is made since it's made from a different Thread.
您可以通过使用以下代码从每个函数调用中输出线程ID来了解有关此内容的更多信息:
You can learn more about this by outputting the Thread id from each function call with the code below:
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
构造函数中创建新实例.
Create the new instance from inside one of Unity's function such as Awake
, Start
instead of MonoBehaviour
constructor.
public class Room : MonoBehaviour
{
public ClassB classBTestInstance;
// Use this for initialization
void Start()
{
classBTestInstance = new ClassB(3);
}
}
这篇关于为什么在非MonoBehaviour类中有多个构造函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!