我想测试并查看游戏对象是否是另一个游戏对象的实例,但我所拥有的似乎并不起作用。我正在尝试创建一个池化脚本来池化项目而不是创建/销毁它们。
以下是我目前正在做的事情:
// Holds all the items that can be instantiated
private List<PoolItems> poolItems = new List<PoolItems>();
// Holds all the pooled items (displayed in the hierarchy active/inactive)
private List<GameObject> gameObjects = new List<GameObject>();
// Here is how I initiate pool items:
void Start(){
for(int i = 0; i < poolItems.Count; i++){
GameObject obj = poolItems[i].prefab;
for (int j = 0; j < poolItems[i].startItems; j++){
GameObject newObj = Create(obj);
newObj.SetActive(false);
gameObjects.Add(newObj);
}
}
}
// The issue is in this method I believe:
public GameObject Instantiate(GameObject obj, Vector3 position, Quaternion rotation){
// Find an inactive object
GameObject foundObject = (
from i in gameObjects
where
i.GetType().IsAssignableFrom(obj.GetType()) &&
i.activeInHierarchy == false
select i
).FirstOrDefault();
}
发生的事情是它只选择列表中的第一项。
以此层次结构为例:
Circle (Clone)
Circle (Clone)
Circle (Clone)
Square (Clone)
Square (Clone)
Square (Clone)
Square (Clone)
当我通过&#34; Square&#34; gameObject到方法,它仍然选择一个&#34; Circle&#34;项目
答案 0 :(得分:1)
您应该做的是为每个实例分配预制件。
public interface IPoolItem{ GameObject Prefab { get;set; } }
也可以代替GameObject创建该类型的集合。 创建新项目并将其放入池中时,还可以为其指定预制件:
void Start(){
for(int i = 0; i < poolItems.Count; i++){
GameObject obj = poolItems[i].prefab;
for (int j = 0; j < poolItems[i].startItems; j++){
GameObject newObj = Create(obj);
newObj.GetComponent<IPoolItem>().Prefab = obj;
newObj.SetActive(false);
gameObjects.Add(newObj);
}
}
}
赋值应该在Create中(但我的问题中没有它),它还应首先检查该对象是否包含IPoolItem组件。然后它会推送列表中的引用。
然后,您可以遍历您的合并项目集合,并获得一个不活动的项目。然后将其预制件与传递给方法的预制件进行比较:
public GameObject Instantiate(GameObject obj, Vector3 position, Quaternion rotation){
foreach(IPoolItem item in poolItems){
if(item.activeSelf == true){continue;}
if(item.Prefab == obj) { return item.gameObject;}
}
return null;
}
有一些方法可以使用Dictionary&gt;来优化它们。当你寻找正方形时,这将节省圆圈的迭代。此外,您可以检查预制件是否已在字典中注册,这样您就不会进行任何迭代。 IPoolItem还可以包含一个充当OnEnable的Init方法,这样当你弹出一个项目时你也可以初始化它。
最后,如果您使用队列而不是列表,则可以在获取时取消队列,并在重置时使用队列。然后您不需要迭代,因为您的队列在前面包含有效项目或为空。