为什么在非MonoBehaviour类中有多个构造函数调用? [英] Why multiple constructor calls in a non MonoBehaviour class?

查看:132
本文介绍了为什么在非MonoBehaviour类中有多个构造函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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函数之一(例如AwakeStart)而不是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆