尝试从静态类获取数据时,Unity中出现NullReferenceException错误

本文关键字:Unity 错误 NullReferenceException 静态类 获取 数据 | 更新日期: 2023-09-27 18:20:32

我正在为我正在开发的本地合作游戏开发存储系统。代码的目标是建立一个Serializable Static类,该类包含四个玩家的实例以及他们需要存储的相关数据,以便以二进制形式保存。

[System.Serializable]
public class GameState  {
//Current is the GameState referenced during play
public static GameState current;
public Player mage;
public Player crusader;
public Player gunner;
public Player cleric;
public int checkPointState;
//Global versions of each player character that contains main health, second health, and alive/dead
//Also contains the checkpoint that was last activated
public GameState()
{
    mage = new Player();
    crusader = new Player();
    gunner = new Player();
    cleric = new Player();
    checkPointState = 0;
    }
}

Player类只包含跟踪玩家统计数据的int,以及是否处于活动状态的bool。当我在游戏场景中的一个类需要从这个静态类中获取数据时,我的问题就来了。当静态类被引用时,它会抛出错误。

    void Start () {
    mageAlive = GameState.current.mage.isAlive;
    if (mageAlive == true)
    {
        mageMainHealth = GameState.current.mage.mainHealth;
        mageSecondHealth = GameState.current.mage.secondHealth;
    } else
    {
        Destroy(this);
    }
}

我是编码的新手,所以我不确定Unity如何与不是从MonoBehaviour继承的静态类交互。我根据一个工作原理非常相似的教程编写了这段代码,所以我不确定问题出在哪里

没有初始化current

一个快速的解决方案是像这样初始化current

 public static GameState current = new GameState();

这是辛格尔顿模式,你可以在网上读到关于它的文章,但Jon Skeet的这篇文章是一个相当不错的起点。

我会考虑将GameState构造函数设为私有,并将current(通常也称为Instance)设为只有getter的属性:

private static GameState current = new GameState();
public static GameState Current 
{
    get { return current; }
}

有很多方法可以做到这一点,特别是如果多线程是一个问题,那么你应该阅读Jon Skeet的帖子。

尝试从静态类获取数据时,Unity中出现NullReferenceException错误

给出另一个视角:如果你想将其实现为静态类,那么它的工作方式不同,从引用类及其数据开始,而不是以构造函数结束

 public class GameState  {
   // not needed here, because static
   // public static GameState current;
   public static Player mage;
   public static Player crusader;
   public static Player gunner;
   [...]
   public static GameState() {
[...]

当然,你的方法现在也会引用这个静态类的静态数据:

   void Start () {
     mageAlive = GameState.mage.isAlive;
     if (mageAlive == true) {
       mageMainHealth = GameState.mage.mainHealth;
       mageSecondHealth = GameState.mage.secondHealth;

如果你想要一个(可序列化!)Singleton-请参阅DaveShaws的答案。