[英]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);
}
}
and here is the output: 这是输出:
As you can see that it says "Hello 3" twice. 你可以看到它说“Hello 3”两次。 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).
在image2中,您将看到只有一个房间实例(当我将房间类C#脚本附加到主摄像机时)。 I didn't attach this script to anything else.
我没有将此脚本附加到其他任何内容上。
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 ,
在Unity中,当在函数外部创建不从MonoBehaviour继承的Object的新实例时,
1 . 1 。 The constructor is called from Unity's main Thread by Unity's script calling mechanism.
Unity的脚本调用机制从Unity的主线程调用构造函数。
2 . 2 。 The constructor is called again but outside the Unity main Thread from a place known as the
MonoBehaviour
constructor. 从一个称为
MonoBehaviour
构造函数的地方再次调用构造函数,但在Unity主线程之外。 You can't even use Unity's API such as GameObject.Find("Cube");
你甚至不能使用Unity的API,如
GameObject.Find("Cube");
in the constructor when that second call is made since it's made from a different Thread. 在构造函数中进行第二次调用,因为它来自不同的Thread。
You can learn more about this by outputting the Thread id from each function call with the code below: 您可以通过以下代码输出每个函数调用的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()
{
}
}
and 和
public class ClassB
{
public ClassB(int testNum)
{
Thread thread = Thread.CurrentThread;
Debug.Log("ClassB Constructor Thread ID: " + thread.ManagedThreadId); ;
GameObject.Find("ok");
}
}
SOLUTION : 解决方案
Create the new instance from inside one of Unity's function such as Awake
, Start
instead of MonoBehaviour
constructor. 从Unity的一个函数内部创建新实例,如
Awake
, Start
而不是MonoBehaviour
构造函数。
public class Room : MonoBehaviour
{
public ClassB classBTestInstance;
// Use this for initialization
void Start()
{
classBTestInstance = new ClassB(3);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.