在 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考虑到您的 cmets 以及您提供的第一个脚本可以完美运行而没有任何错误(因为它应该:没有理由返回错误),我觉得您对 Unity 很陌生。
因此,我建议您先查看 Unity 教程(它们制作精良,可以帮助您了解引擎的基础知识)。你可以找到Roll-a-ball tutorial here。
关于您的问题:
1- 在第一个脚本中,Fill()
方法不会在任何地方调用,您必须执行以下操作:
private void Start()
Fill();
2- 这个Start()
方法来自MonoBehaviour
父类(以及每帧调用的Update()
方法),在场景开始时调用一次.查看this chart 了解统一流是如何产生的。
3- 使用List<GameObject>
或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<GameObject> instanciatedObjects;
将instanciatedObjects = new GameObject[deck.Length];
替换为instanciatedObjects = new List<GameObject>();
将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以上是关于在 Unity C# 中实例化游戏对象列表的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Unity 游戏引擎平台上的单元测试中实例化 MonoBehaviour 对象