Unity OutOfMemoryException List.Add()
本文关键字:Add List OutOfMemoryException Unity | 更新日期: 2023-09-27 17:50:51
我在Unity3D(4.6.1版本)中为我的FPS实现A*搜索算法。目前,我在游戏开始时有一组敌人预制件生成,并附带了Pathfinder.cs脚本。在我的Pathfinder类中,每隔1秒(如果我的目标改变了节点),它调用 star .cs中的FindPath(),查找从自身到目标的新路径。此时,玩家是目标;所以多个敌人可以找到通往同一个地方的路径。
我已经把它都工作了,敌人发现路径如预期。问题是当我的玩家走了一段时间(有时是几步,有时更长),当游戏突然冻结,任务管理器中的Unity.exe进程上升到2GB以上的内存(从~230MB),并且如果我停止场景也不会下降。有时Unity会解冻一秒钟,以便在控制台记录此错误:
OutOfMemoryException: Out of memory
System.Array.Resize[Node] (.Node[]& array, Int32 length, Int32 newSize) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1928)
System.Array.Resize[Node] (.Node[]& array, Int32 newSize) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1912)
System.Collections.Generic.List`1[Node].set_Capacity (Int32 value) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:622)
System.Collections.Generic.List`1[Node].GrowIfNeeded (Int32 newCount) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:100)
System.Collections.Generic.List`1[Node].Add (.Node item) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:91)
AStar.CalculatePath (.Node node) (at Assets/Scripts/AStar.cs:152)
AStar.FindPath (Vector3 startPos, Vector3 endPos) (at Assets/Scripts/AStar.cs:109)
Pathfinder.FindPath () (at Assets/Scripts/Pathfinder.cs:64)
Pathfinder.Update () (at Assets/Scripts/Pathfinder.cs:35)
错误指向我的 star .cs脚本在list.Add(node):
private static List<Node> CalculatePath(Node node) {
List<Node> list = new List<Node>();
while (node != null) {
list.Add(node); //Error here
node = node.parent;
}
list.Reverse();
return list;
}
我一开始有ArrayList,但是它给出了同样的错误。
重要:
当只有一个敌人时,不会发生。只有当场景中有超过1个敌人寻路时才会出现这个错误。我认为这是因为AStar类和打开列表和关闭列表是静态的,所以我尝试将它们更改为在非静态上下文中使用,但错误仍然发生。
我已经将AStar, Pathfinder和Node类粘贴到pastebin中:http://pastebin.com/4pQU9Pwc
任何帮助都非常感谢!谢谢。
看起来可能存在某种循环逻辑,您将节点添加到列表中?在添加节点之前,您是否尝试检查列表是否包含节点?
while (node != null) {
if (!list.Contains(node)) {
list.Add(node);
node = node.parent;
}
else {
break;
}
}
感谢@Altra Viator找到问题的原因,但是最终路径仍然产生奇怪的结果。我改变了CalculatePath方法以包含一个开始节点(敌人当前节点)并添加了一个简单的检查:
if(node == start) {
break;
}
方法现在看起来像这样:
private static List<Node> CalculatePath(Node node, Node start) {
//Retrace the path back through each of the goal nodes parents (to the start node)
List<Node> list = new List<Node>();
while (node != null) {
if (!list.Contains(node)) {
list.Add(node);
if(node == start) {
break;
}
node = node.parent;
}
else {
break;
}
}
list.Reverse();
return list;
}