【问题标题】:Instantiating a list of gameobjects in Unity C#在 Unity C# 中实例化游戏对象列表
【发布时间】:2017-11-25 19:58:00
【问题描述】:

如何使用 c# 在 Unity3D 中实例化 GameObject 列表? 我在检查器窗口中手动填充预制件列表。

下面是我在 Deck.cs 中编写的代码,但我得到“对象引用未设置为对象的实例”。如果你有一个数组的解决方案,那也将不胜感激。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

namespace Assets
{
    class Deck:MonoBehaviour
    {
        public List<GameObject> deck;
        public void Fill()
        {
            GameObject c1 = Instantiate(deck[0]);
            GameObject c2 = Instantiate(deck[1]);
            GameObject c3 = Instantiate(deck[2]);
            GameObject c4 = Instantiate(deck[3]);
            GameObject c5 = Instantiate(deck[4]);
            GameObject c6 = Instantiate(deck[5]);
        }

    }
}

我也试过用数组来做,我得到'你要实例化的对象是空的'

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

namespace Assets
{
    class Deck:MonoBehaviour
    {
        public GameObject card1;
        public GameObject card2;
        public GameObject card3;
        public GameObject card4;
        public GameObject card5;
        public GameObject card6;

        public GameObject[] deck;

        public void Start ()
        {
            deck = new GameObject[5];
            GameObject c1 = Instantiate(card1) as GameObject;
            GameObject c2 = Instantiate(card2) as GameObject;
            GameObject c3 = Instantiate(card3) as GameObject;
            GameObject c4 = Instantiate(card4) as GameObject;
            GameObject c5 = Instantiate(card5) as GameObject;
            GameObject c6 = Instantiate(card6) as GameObject;
        }

    }
}

【问题讨论】:

  • 您在哪一行收到错误消息?这 6 行对我来说似乎没问题(即使我们不知道何时调用 Fill() 方法)。
  • 在 'public List 甲板'
  • 不确定是否引发了此错误:我对其进行了测试,但没有发生错误。查看我的答案以获取更多详细信息。

标签: c# list unity3d gameobject


【解决方案1】:

考虑到您的 cmets 以及您提供的第一个脚本可以完美运行而没有任何错误(因为它应该:没有理由返回错误),我觉得您对 Unity 很陌生。

因此,我建议您先查看 Unity 教程(它们制作精良,可以帮助您了解引擎的基础知识)。你可以找到Roll-a-ball tutorial here

关于您的问题:

1- 在第一个脚本中,Fill() 方法不会在任何地方调用,您必须执行以下操作:

private void Start()
{
    Fill();
}

2- 这个Start()方法来自MonoBehaviour父类(以及每帧调用的Update()方法),在场景开始时调用一次.查看this chart 了解统一流是如何产生的。

3- 使用List&lt;GameObject&gt;GameObject[] 都取决于您的情况:如果集合的大小将发生变化,请查看列表。否则建议使用数组。

4- 考虑到您的脚本,我猜它应该如下所示:

namespace Assets
{
    class Deck : MonoBehaviour
    {
        [SerializeField]
        private GameObject[] deck;

        private GameObject[] instanciatedObjects;

        private void Start()
        {
            Fill();
        }

        public void Fill()
        {
            instanciatedObjects = new GameObject[deck.Length];
            for (int i = 0; i < deck.Lenght; i++)
            {
                instanciatedObjects[i] = Instanciate(deck[i]) as GameObject;
            }
        }
    }
}

如果需要,您当然仍然可以使用列表 :)

编辑:
如果您想使用列表,您只需:

  • private GameObject[] instanciatedObjects; 更改为private List&lt;GameObject&gt; instanciatedObjects;
  • instanciatedObjects = new GameObject[deck.Length]; 替换为instanciatedObjects = new List&lt;GameObject&gt;();
  • instanciatedObjects[i] = Instanciated(deck[i]) as GameObject; 替换为instanciateObjects.Add(Instanciated(deck[i]) as GameObject);

希望对你有帮助,

【讨论】:

  • 感谢您的回答。我也会试试你的代码版本。是的,我对 Unity 真的很陌生 :)
  • 注意到了,这就是为什么我想提供尽可能多的信息:只要您花时间学习 Unity,它的学习速度很快。因为感觉你对 C# 很熟悉,所以不需要很长时间就能掌握它 :)
  • 我试过你的解决方案,效果很好!如果是列表,当我尝试按索引调用实例化对象时,我会出现超出范围的异常。该阵列虽然很好用。非常感谢您的帮助,我终于完成了几个小时以来一直想做的事情。
  • 抱歉忘记回复您的评论:很高兴它运作良好。我编辑了答案以添加使用列表而不是数组所需的更改。
【解决方案2】:

使用 foreach 通过预制件循环遍历您的列表,如下所示:

public List<GameObject> Deck = new List<GameObject>(); // im assuming Deck is your list with prefabs?
public List<GameObject> CreatedCards = new List<GameObject>();

void Start()
{
     Fill();
}

public void Fill()
{
    foreach(GameObject _go in Deck)
    {
        GameObject _newCard = (GameObject)Instantiate(_go);
        CreatedCards.Add(_newCard);
    }
}

用大写字母命名列表也是一个好习惯。

【讨论】:

  • 它没有给出任何错误,但它也没有创建任何实例。 :( CreatedCards 列表一直是空的
  • 你的牌组里装满了游戏对象吗?还要检查编辑 - 我忘了 new List()
  • 不,如果我调用函数 Start 而不是 Fill,它会起作用
  • 如果你想实例化它们,你需要用一些预制件填充你的甲板。还要检查编辑 - 我忘了 new List()
  • 我用预制件填充了它,是的,现在它可以工作了,但我不得不将函数重命名为 Start。我不确定为什么它不能以另一种方式工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
  • 2019-05-28
相关资源
最近更新 更多