c# - 为什么在非 MonoBehaviour 类中调用多个构造函数?

标签 c# unity3d

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);
    }
}

这是输出:

enter image description here

如您所见,它说了两次“Hello 3”。我想了解为什么会这样?我不知道我在哪里打了两次电话。在图像 2 中,您将看到只有 1 个房间实例(当我将房间类 C# 脚本附加到主摄像头时)。我没有将此脚本附加到任何其他内容。

enter image description here

最佳答案

这真是个好问题。在 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 的函数之一(例如 AwakeStart 而不是 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/

相关文章:

c# - 如何获取具有指定属性的所有字段的列表?

c# - 如何强制重绘我的场景?

c# - 与地面上的 "dirt"碰撞时放慢播放器

android - Unity proguard:任务 ':transformClassesAndResourcesWithProguardForRelease'的执行失败

c# - 如何创建以终点为鼠标位置但仅面向一个方向的线渲染器

c# - 获取特定版本的 TFS API

c# - 如何同时获取行数和行数

c# - HashSet 中的剩余值进入辅助输出

c# - 未经授权修改 $expand 函数的 Bind(ing)

git - 在版本控制中忽略文件夹元文件