【问题标题】:Unity3D: List returns null when accessed from other classUnity3D:从其他类访问时列表返回null
【发布时间】:2016-02-04 20:30:41
【问题描述】:

我目前正在尝试在 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);

    }
}

我需要从中调用方法的脚本:

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)));
        }
    }

}

【问题讨论】:

    标签: c# list unity3d pooling


    【解决方案1】:

    您可以将FoodManager 中的Awake() 更改为Start(),以确保首先调用ObjectPool 中的代码。

    或者您可以为这两个类显式设置脚本执行顺序。这是通过转到Edit &gt; Project Settings &gt; Script Execution Order 菜单并添加两个脚本来完成的,ObjectPool 的排名高于FoodManagerSource

    【讨论】:

    • 全部正确。只是为了记录,用执行顺序鬼混真的很危险(而且毫无意义),这是一种黑客行为。对于这样一个简单的问题,绝对没有理由这样做。只需使用 Unity 事件或只调用另一个事件! 进行此类设置
    • 天哪,我现在觉得自己很蠢! :) 我显然在寻找所有错误的地方!我没有注意到我已经把食品经理的东西放在了清醒状态.. Duh!在某一时刻唤醒是必要的,但这与我最近的更改无关..只是忘记将其更改回开始!现在完美运行,感谢您的帮助!
    • 我赞成一个叫另一个的想法。如果您让 Cat 依赖 Owner 处于特定状态,那么您不能仅仅假设如果您不确定 100% 会是这样。很多次,你在编辑器中运行,一切都很好,然后你在设备上运行,顺序改变了,badoom。最好(在我看来)让所有者在 Cat 上调用 init 并将自身作为参数传递(通过接口)。然后,您 110% 确定 Cat 需要时 Owner 的状态。
    • @fafase 我很想听听您的偏好...我似乎无法理解您为什么要将 Owner 作为参数传递给 Cat。
    • 认为你的猫的行为取决于主人的行为,假设主人粗心,猫会流浪,如果主人是细心的小女孩,猫会变成好猫。猫需要知道主人的状态。如果你把 owner 设置为 Awake 并且猫也读取了 awake 的 state,你不能保证 owner 先做。但是从 Owner 你调用 cat.Init(this as IOwnerBehaviour);当一切都完成后,你的猫肯定会根据主人的状态进行设置。有点难以在 cmets 中清楚地解释。
    猜你喜欢
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    相关资源
    最近更新 更多