我正在Unity中创建2D太空飞船游戏。我有一个标题为“播放器”的对象,并附有此脚本。在脚本中,我有这个类代表玩家的船:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList;
void Start()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
这个类(在同一个脚本中)代表武器:
public class Weapon
{
//properties here
}
现在,当我尝试使用此代码(来自不同的脚本)引用weaponList来获取List.Count时,它会抛出NullReferenceException,说Object引用未设置为对象的实例:
Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship.weaponsList.Count >=2)
{
//do stuff
}
但我试图访问的任何其他船舶属性都可以。有人可以帮忙吗?如果您需要其他背景信息或代码,请告诉我,我会进行必要的修改。
编辑:启动方法对Unity来说是特殊的,并且在脚本初始化时始终默认调用。
答案 0 :(得分:1)
船舶不包含武器清单。
您可以使用
来避免异常Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship != null && ship.weaponsList != null && ship.weaponsList.Count >=2)
{
//do stuff
}
¿方法Start()是否被调用?
答案 1 :(得分:1)
要避免此错误向您的班级添加构造函数
public class Ship : MonoBehaviour
{
public Ship()
{
weaponsList = new List<Weapon>();
}
public List<Weapon> weaponsList;
void Start()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
答案 2 :(得分:1)
如果weaponsList
未被调用,则null
为Start()
,或者在某个时刻变为null
。将公共变量更改为公共属性以拒绝外部调用者更改内部列表:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList { get; private set; }
public Ship()
{
weaponsList = new List<Weapon>();
}
...
}
这可能会在应用程序的其他部分中产生编译器错误。这些错误可能是weaponsList
成为null
的原因。
在更好的编码实践方面,还有一些更改建议的建议:
public IList<IWeapon> Weapons { get; private set; }
List
更改为界面。Weapon
更改为IWeapon
。Weapons
,而非weapons
)。Weapons
,而不是WeaponsList
(列表很明显)答案 3 :(得分:0)
而不是将武器列表的初始化放在void Start()
中,而是将它放在对象的构造函数中。然后,当船舶被创建时,武器列表将始终以零计数进行初始化。构造函数应始终将有问题的对象置于有效状态,以便可以使用它。有时,程序员创建Init()或Start()方法来推迟昂贵的逻辑,直到方法实际需要它,但在这种情况下,我肯定会将该初始化放在构造函数中。
答案 4 :(得分:0)
在调用Start()
时构建列表。如果在访问列表之前未调用Start()
,则会显示错误。我的猜测是你在调用Start()
之前尝试访问列表。
您应该考虑为Ship
类构建构造函数并将初始化代码放在那里:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList;
public Ship()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
只要创建了类的对象,就会调用此构造函数,并且您不必显式调用方法来构造对象的属性。