我在团结中制作游戏。在游戏中,当玩家向前移动时,关卡会在场景中随机生成新对象。
因此,当玩家向前移动时,是否有必要删除/销毁先前生成的对象?
它会改善内存使用吗?
提前致谢。
答案 0 :(得分:1)
除非你是初学者并且只是搞乱Unity3D,否则生成并销毁对象。如果你计划发布任何游戏,那就不是没有。不要这样做!
因此有必要删除/销毁先前生成的对象 当玩家向前移动时?
它会改善内存使用吗?
如果生成新对象,则必须删除/销毁对象,否则会耗尽内存。 但是生成和删除/销毁GameObject会降低你的游戏速度,因为这会调用垃圾收集器。
正确执行此操作的方法是使用名为对象池的内容。 您必须创建自己的对象池类。
很长的解释但我会尽量保持简短。
对象池通过重新使用游戏对象而不是实例化/生成新对象和销毁旧对象来工作。
有很多方法可以做到这一点,但我会谈谈我的方式。
找出假设在场景中的最大对象。 让你的枪使用7发子弹的那一天,你需要20个子弹用于你的FPS游戏。
在游戏开始之前,在场景中创建20个项目符号并通过禁用所有项目来隐藏它们。
在start
或Awake
函数中,获取 更改>的项目符号的所有属性 强>当你射击时。 转换和轮播/四元数是通常会发生变化的事情之一。
Vector3 defaultPosition = bullet.transform.position; 四元数defaultRotation = bullet.transform.rotation;
有一个bool变量来确定子弹的使用时间,以便在它不再使用之前无法恢复。我们可以称之为bool isInUse = false
;
设置重置功能以重置项目符号。在重置内,你所要做的就是在拍摄时重置那些更改 默认值的值,然后禁用强>子弹。同时将isInUse
设置为false。
例如,
void reset {
bullet.transform.position = defaultPosition;
bullet.transform.rotation = defaultRotation;
bullet.SetActive(假);
isInUse = false;
}
创建一个名为" WaitForReset"的协同程序函数。确定子弹应该重置的时间。 你可以根据它已经被覆盖的距离重置子弹,在它被射击后或者碰撞时已经离开了多少秒另一个GameObject。这取决于您实施。我下面的那个将等待5秒,然后重置GameObject / bullet。
`IEnumerator WaitForReset(){
yield返回新的WaitForSeconds(5);
复位();
}`
要拍摄子弹,检查,如果属性isInUse
的20个子弹中有一个是false
,则加载第一个返回false
。如果当前子弹是“使用”,请转到下一个。一旦你射击子弹,调用WaitForReset()函数,以便子弹可以在以后重置。
StartCoroutine(WaitForReset());
这将一次又一次地发生而不分配和释放内存,从而提高了游戏的速度。
在建筑物等场景中解决大型独特模型的问题。 假设你有大量具有HQ纹理的对象,那么池化可能不是解决这个问题的最佳方法。
应使用详细程度( LOD )。所以基本上你为每个大型GameObject创建了多个3D模型。高详细的对象,中间的细节,低细节和真正的行详细多边形。
当你远离那个物体时,Unity只会显示低细节的3D模型。一旦您靠近物体,Unity就会自动将3D模型与高详细的3D模型交换。这改善了游戏的记忆和速度。要了解如何设置Google"详细程度统一"并观看视频。它需要视觉才能理解。
答案 1 :(得分:0)
Unity不会为您删除实例化的GameObjects。我不知道你在谈论什么样的关卡,但是如果它是某种无限级别你最终必须处理内存并且可能需要删除创建的GameObjects。
如果可以重用那些GameObjects,你应该看看一个名为" Object Pooling"的方法。这是Unity的官方视频教程:
https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/object-pooling
注意:这只是对稀疏信息的建议。根据您的级别类型,根本不删除GameObjects也是有意义的。例如,当您不希望它们消失时,因为您可以重新访问该级别的某些部分,并且内存使用率很低,需要关注。 (在Unity编辑器的“游戏”窗口中激活统计面板。)