C# Unity3D:从其他类访问时,列表返回null

C# Unity3D:从其他类访问时,列表返回null,c#,list,unity3d,pooling,C#,List,Unity3d,Pooling,我目前正试图在unity3D中制作一款小型手机游戏,正如我经常听到的那样,使用实例化/销毁是一种非常糟糕的方式(尽管我从未制作过任何足够大的游戏,但这实际上成为了一个问题),我决定尝试在池系统中制作 我创建了一个脚本,用于处理两个单独列表中的所有池对象。通过从脚本本身调用该方法,我可以成功地从池中生成一个对象,但问题是,当我尝试从另一个脚本调用该方法时,它不起作用。通过不同的尝试,我得到了空引用异常或错误: 由于对象的当前状态,操作无效 System.Linq.Enumerable.First[

我目前正试图在unity3D中制作一款小型手机游戏,正如我经常听到的那样,使用实例化/销毁是一种非常糟糕的方式(尽管我从未制作过任何足够大的游戏,但这实际上成为了一个问题),我决定尝试在池系统中制作

我创建了一个脚本,用于处理两个单独列表中的所有池对象。通过从脚本本身调用该方法,我可以成功地从池中生成一个对象,但问题是,当我尝试从另一个脚本调用该方法时,它不起作用。通过不同的尝试,我得到了空引用异常或错误:

由于对象的当前状态,操作无效 System.Linq.Enumerable.First[GameObject](IEnumerable`1源)

我真的找不到其他人有这个问题。而且似乎相关的解决方案也不起作用。主要问题也可能是。。为什么会发生这种情况

池脚本:

public class ObjectPool : MonoBehaviour {


    GameObject basicCell;
    GameObject basicFood;

    private Vector3 poolSpawnPos;

    [SerializeField]
    private int cellAmount;

    [SerializeField]
    private int foodAmount;

    List<GameObject> cellPool;
    List<GameObject> foodPool;

    GameObject foodManager;
    GameObject cellManager;
    // Use this for initialization
    void Awake () {

        foodManager = gameObject.transform.FindChild ("FoodPool").gameObject;
        cellManager = gameObject.transform.FindChild ("CellPool").gameObject;

        cellPool = new List<GameObject> (cellAmount);
        foodPool = new List<GameObject> (foodAmount);
        poolSpawnPos = new Vector3 (8000, 8000, 8000);
        basicFood = Resources.Load ("Food/BasicFood/BasicFood") as GameObject;
        basicCell = Resources.Load ("Cell/Cell") as GameObject;
        for (int i = 0; i < cellAmount; i++) {
            GameObject currentCell = Instantiate(basicCell, poolSpawnPos, Quaternion.identity) as GameObject;
            currentCell.transform.parent = cellManager.transform;
            currentCell.SetActive (false);
            cellPool.Add (currentCell);

        }

        for (int i = 0; i < foodAmount; i++){
            GameObject currentFood = Instantiate(basicFood, poolSpawnPos, Quaternion.identity) as GameObject;
            currentFood.transform.parent = foodManager.transform;
            currentFood.SetActive (false);
            foodPool.Add (currentFood);
        }
    }

    // Update is called once per frame
    void Update () {
        //if(foodPool.Count > 0)
        //  SpawnFood (new Vector3 (0, 0, 0));
    }

    public void SpawnFood(Vector3 spawnPosition)
    {
        GameObject selectedFood = null;
        selectedFood = foodPool.First();
        print (selectedFood);
        selectedFood.SetActive (true);
        foodPool.Remove (selectedFood);

        selectedFood.transform.parent = null;
        selectedFood.transform.position = spawnPosition;


        //set food Stats


    }


    public void KillFood(GameObject killedFood)
    {
        foodPool.Add (killedFood);
        killedFood.transform.position = poolSpawnPos;
        killedFood.transform.parent = foodManager.transform;
        killedFood.SetActive (false);

    }
}
公共类对象池:单行为{
游戏对象basicCell;
游戏对象基本食物;
私人向量3;
[序列化字段]
私人金额;
[序列化字段]
私人国际食品山;
列出细胞池;
列出foodPool;
游戏对象食物管理器;
游戏对象管理器;
//用于初始化
无效唤醒(){
foodManager=gameObject.transform.FindChild(“FoodPool”).gameObject;
cellManager=gameObject.transform.FindChild(“CellPool”).gameObject;
cellPool=新列表(cellAmount);
foodPool=新列表(foodAmount);
poolSpawnPos=新矢量3(8000,8000,8000);
basicFood=Resources.Load(“Food/basicFood/basicFood”)作为游戏对象;
basicCell=Resources.Load(“单元格/单元格”)作为游戏对象;
对于(int i=0;i0)
//产卵食物(新载体3(0,0,0));
}
公共空间产卵食物(矢量3产卵位置)
{
GameObject selectedFood=null;
selectedFood=foodPool.First();
印刷品(精选食品);
selectedFood.SetActive(true);
foodPool.移除(选定的食物);
selectedFood.transform.parent=null;
selectedFood.transform.position=繁殖位置;
//设定食物统计
}
公共空间食物杀手(游戏对象食物杀手)
{
foodPool.Add(killedFood);
killedFood.transform.position=poolspawnprownpos;
killedFood.transform.parent=foodManager.transform;
killedFood.SetActive(false);
}
}
需要从中调用方法的脚本:

public class FoodManager : MonoBehaviour {

    public ObjectPool pool;
    public int initialFoodNumber = 50;

    void Awake()
    {
        pool = GameObject.Find("ObjectPool").GetComponent<ObjectPool>();

        for (int i = 0; i <= initialFoodNumber; i++)
        {
            pool.SpawnFood(new Vector3(Random.Range(-40, 41), 0, Random.Range(-40, 41)));
        }
    }

}
公共类FoodManager:MonoBehavior{
公共对象池;
public int initialFoodNumber=50;
无效唤醒()
{
pool=GameObject.Find(“ObjectPool”).GetComponent();

对于(int i=0;i您可以将
FoodManager
中的
Awake()
更改为
Start()
,以确保首先调用
ObjectPool
中的代码


或者,您可以显式设置这两个类的脚本执行顺序。这可以通过转到
Edit>Project Settings>script execution order
菜单并添加这两个脚本来完成,
ObjectPool
的排名高于
FoodManager

全部为真。仅就记录而言,这是非常危险的(而且毫无意义)玩弄执行令,这是一个黑客行为。对于这么简单的问题,绝对没有理由这么做。只需使用一个统一事件或从另一个事件中调用一个就行了!对于这样的设置,我现在觉得自己很愚蠢!:)我显然找错地方了!我没注意到我把食品经理的东西放在了醒着的状态下……嗯!醒着在某一点上是必要的,但这不是我最近的改变……只是忘了把它改回原来的状态!现在效果很好,谢谢你的帮助!我会赞成一个叫另一个的想法。如果你有猫依赖它的话Owner要处于特定状态,如果您不能100%确定,您不能仅仅假设它将处于特定状态。很多时候,您在编辑器中运行,一切正常,然后您在设备上运行,并且顺序发生了更改和错误。在我看来,让Owner调用Cat上的init作为参数(通过接口)传递自己是更好的那么,当猫需要它的时候,你可以肯定地知道主人的状态是什么。“FAFASE,我很想听到更多关于你的偏好……我似乎不知道你为什么要把主人送猫作为一个参数。考虑你的猫的行为取决于主人的行为,如果猫是粗心的或是主人的话,猫就会变得流浪。如果主人是一个细心的小女孩,那它就是一只好猫。猫需要知道主人的状态。如果你把主人设置为醒着,猫也在醒着的状态下读取状态,你不能保证主人先完成。但是从主人那里你叫cat.Init(这是IOwnerBehaviour);在醒来的最后,当一切都完成后,你的猫肯定会根据主人的状态进行调整。在评论中很难解释清楚。