当前位置: 首页 > 知识库问答 >
问题:

我正在研究Unity的C#构造函数和析构函数,但我不知道它为什么会这样工作

梅安平
2023-03-14

我正在用unity组件系统学习C#的构造函数和析构函数。< br >如果这个问题的英文很奇怪,我很抱歉。我用了一个翻译,因为我不擅长英语。日志输出是这样的。

  1. 在不按播放按钮的情况下显示构造器日志。为什么
  2. 当我按下播放按钮时,我看到一个正在创建并立即消失的日志。游戏开始后,我没有编写代码来创建对象,这个短语在哪里运行

这是我的代码。

项目工作结构

按下空格键将预制的prefab带到游戏世界,Prefab有一个附加的组件来测试构造函数和析构函数。

当按下空格键时,它会创建一个预置。< br >此组件被附加到“游戏对象”游戏对象

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeFactory : MonoBehaviour
{
    public GameObject obj;
    private int pos = 1;
    void Start()
    {   
    }
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Instantiate(obj,new Vector3(pos,0,0),Quaternion.identity);
            pos++;
        }
    }
}

用于测试构造函数和析构函数的组件。它附加了立方体预制。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ClassTest : MonoBehaviour
{
    public ClassTest(){
        Debug.Log("I was born!");
    }
    ~ClassTest(){
        Debug.Log("I Died x0x");
    }
}

这是我的项目文件。(不好意思压缩一下。我还没有学会如何使用Git。)

共有2个答案

能正青
2023-03-14

古老的智慧说,只有当你的类包含非托管内存中对象的句柄(IntPtr)时,才应该使用C#终结器。如果您不清楚这意味着什么,那么您可能不需要使用终结器;无论哪种方式,您都永远不需要在统一引擎对象派生类中使用它们。

相反,请选择以下任何一种Unity信息:

void OnDestroy()
{
  // (1) called when the Object is about to be fully destroyed.
}
void OnDisable()
{
  // (1) called when the Object is disabled in the Scene hierarchy.
  //     OR
  // (2) called right before OnDestroy() would be called.
}

这些Unity消息当然可以用于单行为,但也可以用于所有脚本对象!(对于后者,OnDisable本质上解析为与ondstroy,因为它们不是场景绑定对象。)

同样,您也应该避免在MonoBehaviours和ScriptableObjects上使用C#构造函数。更喜欢的消息是:

  • 虚空清醒()
  • 空位开始()
  • void OnEnable()

每个都有自己的怪癖,所以你可能想熟悉这些差异并编写一些测试。

您可以在这里参考相关的留档:(见标题“消息”部分)

  • 单一行为文档
  • 脚本对象文档
梁修贤
2023-03-14

请更改您的ClassTest.cs脚本以使用更简单的函数。永远不要在Unity中使用构造器和终结器。我从你的逻辑中理解的是,当你按空格键时,一个对象被实例化。ClassTest.cs附加到这个对象上。更好的用途:

  void Start()
    {
      Debug.Log("I was born!"); //Will be called when the gameObject is active for the first time
    }

现在,您还想知道游戏对象是否已被销毁,您可以使用附加到始终处于活动状态的游戏对象的另一个脚本执行此操作,例如:

public GameObject cube;

    void Update()
    {
        cube= GameObject.Find("Cube(Clone)"); //Depending on how your object is called
        if(cube == null)
        {
         Debug.Log("Either not created or is destroyed");
        }
     }

我使用了Update(),它在每一帧调用。您可以使用希望从另一个脚本调用一次的不同函数。

 类似资料:
  • 我在做一个非常简单的两个按钮状态。如果我点击abutton,A组件显示,如果点击bButk,那么B组件。我正在映射通过数组的项目,以便每个项目都有自己的按钮状态。假设我点击项目1的按钮B,那么我只想要第一个项目B显示。现在所有这些都会同时被触发。我已经在构造函数中限制了它们,但我仍然无法只获得一次点击触发并显示相关组件。

  • 这就是问题和我的Javascript解决方案 您将获得指向链表头节点的指针和一个要添加到列表中的整数。使用给定的整数创建一个新节点。在链表的尾部插入此节点,并返回插入此新节点后形成的链表的头节点。给定的头指针可能为null,这意味着初始列表为空。

  • C++ 类 & 对象 类的构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。 下面的实例有助于更好地理解构造函数的概念:#include <iostream> using namespace std; class Line { public: v

  • 类 类是对某一事物的抽象描述,具体地讲,类是C++中的一种构造的数据类型。它即可包含描述事物的数据,又可包含处理这些数据的函数,类在程序运行时是被用作样板来建立对象的。所以要建立对象,首先必须定义类。 定义类 定义一个类的一般格式为: class 类名{     private:         成员表1;     public:         成员表2;     protected:     

  • 我正在尝试编写一个Python实用程序,将Oracle的RAW字节字符串(作为字符串)转换为Guid,反之亦然。我试图重用我在C#中构建的同一个实用程序中的算法,但是从同一个字节数组构造一个和一个会产生不同的Guid/UUID。它们是一样的,不是吗?我读过UUID只是一个更好的术语。 在C#中,我有一个字节数组,< code>byte_array如下所示: 在 Python 中,我有一个字节数组,

  • 类构造函数 类constructor是类的特殊成员函数,只要我们创建该类的新对象,就会执行该函数。 构造函数与类具有完全相同的名称,它根本没有任何返回类型,甚至无效。 构造函数对于为某些成员变量设置初始值非常有用。 下面的例子解释了构造函数的概念 - #include <iostream> using namespace std; class Line { public: voi