【发布时间】:2019-04-05 14:48:54
【问题描述】:
我为 Unity 中的任何游戏对象实现了一个通用池系统。 当我从 List 中删除一个 GameObject 时,我总是取最后一个,以避免在 List 的实现中使用的数组发生移位。在互联网上没有找到任何有用的东西,所以试图自己弄清楚。 那有用还是我只是在做无用的代码?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolSystem : MonoBehaviour
{
public static Dictionary<string, List<GameObject>> pool = new Dictionary<string, List<GameObject>>();
#region cached
private static GameObject lastReturned;
#endregion
public static GameObject GetElementFromPool(GameObject g)
{
if (!pool.ContainsKey(g.name))
{
lastReturned = Instantiate(g) as GameObject;
pool.Add(g.name, new List<GameObject>());
lastReturned.name = g.name;
return lastReturned;
}
if (pool[g.name].Count == 0)
{
lastReturned = Instantiate(g) as GameObject;
lastReturned.name = g.name;
}
else
{
lastReturned = pool[g.name][pool[g.name].Count - 1];
pool[g.name].RemoveAt(pool[g.name].Count - 1);
}
return lastReturned;
}
public static void AddToPool(GameObject g)
{
if (!pool.ContainsKey(g.name))
{
pool.Add(g.name, new List<GameObject>());
}
pool[g.name].Add(g);
}
}
我在答案和cmets中添加了所有建议,感谢大家的帮助。在下面添加更改的代码,也许有人会发现它有用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolSystem : MonoBehaviour
{
public static Dictionary<string, Stack<GameObject>> pool = new Dictionary<string, Stack<GameObject>>();
#region cached
private static GameObject lastReturned;
private static Stack<GameObject> lastUsedStack;
#endregion
public static GameObject GetElementFromPool(GameObject g)
{
if (pool.TryGetValue(g.name, out lastUsedStack))
{
if (pool[g.name].Count == 0)
{
lastReturned = Instantiate(g) as GameObject;
lastReturned.name = g.name;
}
else
{
lastReturned = pool[g.name].Pop();
}
}
else
{
lastReturned = Instantiate(g) as GameObject;
pool.Add(g.name, new Stack<GameObject>());
lastReturned.name = g.name;
return lastReturned;
}
return lastReturned;
}
public static void AddToPool(GameObject g)
{
if (!pool.ContainsKey(g.name))
{
pool.Add(g.name, new Stack<GameObject>());
}
pool[g.name].Push(g);
}
}
【问题讨论】:
-
@Neil .NET 列表是基于一个数组的,它是实际上是在移除元素时移动的。双向链表会有可怕的随机访问时间。
-
作为一个附带问题,不要像那样使用
ContainsKey。请改用TryGetValue,以避免进行两次哈希查找。