unity OutOfMemoryException List.Add()
Unity OutOfMemoryException List.Add()
我正在 Unity3D(版本 4.6.1)中为我的 FPS 实现 A* 搜索算法。目前,我有一定数量的敌人预制件在游戏开始时生成,并附有 Pathfinder.cs 脚本。在我的 Pathfinder class 中,每 1 秒(如果我的目标更改了节点),它会在 AStar.cs[=37 中调用 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)
错误指向我的 AStar.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 个敌人时 不会 发生此错误。该错误仅在场景中有超过 1 个敌人寻路时发生。我以为这是因为 AStar class 和 open 和 closed 列表是静态的,所以我尝试将它们更改为在非静态上下文中使用,但仍然出现错误。
我已将 AStar、Pathfinder 和 Node classes 粘贴到 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;
}
我正在 Unity3D(版本 4.6.1)中为我的 FPS 实现 A* 搜索算法。目前,我有一定数量的敌人预制件在游戏开始时生成,并附有 Pathfinder.cs 脚本。在我的 Pathfinder class 中,每 1 秒(如果我的目标更改了节点),它会在 AStar.cs[=37 中调用 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)
错误指向我的 AStar.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 个敌人时 不会 发生此错误。该错误仅在场景中有超过 1 个敌人寻路时发生。我以为这是因为 AStar class 和 open 和 closed 列表是静态的,所以我尝试将它们更改为在非静态上下文中使用,但仍然出现错误。
我已将 AStar、Pathfinder 和 Node classes 粘贴到 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;
}