在 Update() 方法中创建新对象

Meh*_*hDi 2 c# garbage-collection unity-game-engine unity5

我在某处读到我不应该在游戏引擎的 Update() 方法中创建任何新对象实例,因为这会导致唤醒垃圾收集器并降低性能,但有时我在一些教程中看到他们使用 new 关键字unity Update() 方法!这个可以吗?团结会以某种方式处理这个问题,还是不?

Pro*_*mer 6

这对于新的 C# 程序员来说是一件令人困惑的事情。

这个可以吗?

答案取决于您使用new关键字的数据类型。这基本上是值类型与引用类型。有关更多信息,请参阅此答案末尾的链接。

  • 如果是 a class,则不要new在Update函数中使用关键字 。使用对象池,否则您将在每一帧创建新对象。是的,这是昂贵的。
  • 如果是 a struct,则可以new在Update没有的函数中随意使用其上的关键字。

你可能在Update函数中看到过这样的代码:

Vector3 vec = new Vector3(0, 0, 0);
Run Code Online (Sandbox Code Playgroud)

这很好,因为Unity的Vector3 是struct不是class。

在此处输入图片说明


另一个例子是这个Update函数:

GameObject obj = new GameObject("MyObject");
Run Code Online (Sandbox Code Playgroud)

这很糟糕,因为GameObject是一个class. 您正在每帧创建一个游戏对象。在Start函数中执行一次,然后重新使用它。您还可以使用对象池。

在此处输入图片说明

请注意红色圆圈文本,您可以使用它来确定您使用的 API 是 aclass还是 a struct。

以下是其他需要了解的事项:

1. C# 值类型 vs 引用类型

2.回收值类型统一有没有意义

3. .NET 中的 struct 和 class 有什么区别?

4. Unity 中的对象池


请注意,此答案侧重于new在您的问题中提到的 Unity 中使用关键字。还有其他一些东西甚至可以在不使用new关键字的情况下分配内存。示例包括param在函数参数中使用关键字、在函数中返回数组、使用yield return 0代替yield return null。

团结会以某种方式处理这个问题,还是不?

唯一可以回答这个问题的是运行此代码的设备。通常,由于 GC 运行,您在移动设备上会遇到一些问题。对象池在移动设备上非常重要。