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

这是输出:

在此输入图像描述

你可以看到它说“Hello 3”两次。 我希望了解为什么会出现这种情况? 我没看到我把它叫了两次。 在image2中,您将看到只有一个房间实例(当我将房间类C#脚本附加到主摄像机时)。 我没有将此脚本附加到其他任何内容上。

在此输入图像描述

这真是一个很好的问题。 在Unity中,当在函数外部创建不从MonoBehaviour继承的Object的新实例时,

1 Unity的脚本调用机制从Unity的主线程调用构造函数。

2 从一个称为MonoBehaviour构造函数的地方再次调用构造函数,但在Unity主线程之外。 你甚至不能使用Unity的API,如GameObject.Find("Cube"); 在构造函数中进行第二次调用,因为它来自不同的Thread。


您可以通过以下代码输出每个函数调用的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()
    {

    }
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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