简体   繁体   English

为什么在非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);
    }
}

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的一个函数内部创建新实例,如AwakeStart而不是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM