在 Unity C# 中实例化游戏对象列表

Posted

技术标签:

【中文标题】在 Unity C# 中实例化游戏对象列表【英文标题】:Instantiating a list of gameobjects in 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 甲板' 不确定是否引发了此错误:我对其进行了测试,但没有发生错误。查看我的答案以获取更多详细信息。 【参考方案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。我不确定为什么它不能以另一种方式工作

以上是关于在 Unity C# 中实例化游戏对象列表的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Unity 游戏引擎平台上的单元测试中实例化 MonoBehaviour 对象

在 Unity 中创建后引用实例化对象

获取其他玩家实例化的游戏对象 Unity Photon

当对象在运行时实例化时,如何使 Unity UI 对象可拖动?

实例化对象出现在层次结构中但不在场景中

如何为在播放模式下实例化并在 Unity 3d 中使用相机位置重新创建的对象添加视差