
了解使用Unity的优化,为游戏开发提供动能,首先必须了解堆与堆栈,这俩个东西大家其实不用想的太复杂,只是内存区域,它俩各有长处和短处。
栈:
它是一个线性结构,它以后进先出 (LIFO) 的方式删除信息,它具有固定大小并且速度非常快,用于非全局变量的局部变量,由于其固定大小,它只能在发生称为堆栈溢出的错误之前存储这么多数据。
另一方面,堆可以随机访问,必要时可以自行调整大小,这种更大的灵活性是有代价的,但是,堆速度较慢并且会产生垃圾收集。
Unity中的所有数据类型都存储在堆或堆栈中,下面是一些区别图。

最后要知道的是值类型和引用类型之间的区别。
Unity中的所有数据类型要么是值类型,要么是引用类型。像int或struct这样的值类型将存储在堆栈中,类或字符串将存储在堆上。
例如:

对于值类型,变量的内容/值与变量一起存在,引用类型包含对对象在内存中位置的引用。
例如:

我们可以使用这些信息来优化游戏。
例如,当从游戏对象获取网格渲染以更改颜色时,可能听说过缓存获取组件。这将节省性能,但由于Renderer是引用类型,因此会有垃圾收集。
public class Renderer : Component
public Renderer();
但是…如果使用像颜色这样的结构,就不会发生这种情况。
例如:
bublic struct color : IEquatable<color>, IFormattable
...public float r;
...public float g;
...public float b;
...public float a;
如果需要了解Unity如何对某些内容进行分类,可以将鼠标悬停在它上面并按f12。
这里另外举个例子:
可能听说过在unity中使用new关键字会创建垃圾回收,这仅适用于引用类型,如果使用像vector3(结构)这样的值类型,那么就没有垃圾回收。当然,如果正在创建一个类的新实例,则会有垃圾收集。
虽然可能没有垃圾收集,但仍然需要小心复制不必要的代码,下面是一个移动代码,而不是使用一个vector3,创建了两个。
if (Input.GetKeyDown(Keycode.D))
{
transform.position = new Vector3(1, 0, 0);
}
else if (Input. GetKeyDown( Keycode.A))
{
transform.position = new Vector3(-1, 0, 0);
}
虽然这比引用类型更好,但更好的方法是重用结构来执行这两个调用。
Vector3 pos = transform.position;
if (Input.GetKeyDown( Keycode.D))
{
pos.x= 1;
}
else if ( Input.GetKeyDown(KeyCode.A))
{
pos.x= -1;
}
transform.position = pos;
在开始之前的最后一件事,为了更容易找到性能峰值,可以编写可以在分析器中找到的自定义消息。
假设…想看看在创建新游戏对象时创建了多少垃圾回收。
首先…
需要一个名为Unity.Engine.Profiling的命名空间,然后使用以下代码开始示例。

然后创建游戏对象并结束示例。
Profiler.BeginSample( "Game0bject Created");
Gameobject go = new GameObject();
Profiler.EndSample();
在分析器中,就可以看到新游戏对象创建了40B的垃圾回收。(了解分析器可参阅站内文章:Unity中的分析器)

以上只是可以用来优化游戏的一些工具,可以用来参考。
如果你有任何反馈,请随时在本页面下方留言。