从列表中选择游戏对象的实例
本文关键字:对象 实例 游戏 选择 列表 | 更新日期: 2023-09-27 18:26:29
我想测试一下游戏对象是否是另一个游戏对象的实例,但我所拥有的似乎不起作用。我正在尝试制作一个池化脚本来池化项目,而不是创建/销毁它们。
以下是我目前正在做的事情:
// 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)
当我将一个"方形"gameObject传递给该方法时,它仍然会选择一个"圆形"项目。
您应该做的是将预制件分配给每个实例。
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>来优化这一切,当你寻找正方形时,它可以省去圆形的迭代。此外,您还可以检查predb是否在字典中注册,这样就不会白白迭代。IPoolItem还可以包含一个Init方法,该方法将充当OnEnable,这样当您弹出一个项目时,您也可以对其进行初始化。
最后,如果您使用队列而不是列表,则可以在获取时退出队列,在重置时加入队列。然后您就不需要迭代了,因为您的队列前面包含一个有效的项或者是空的。