简体   繁体   中英

NullReferenceException error in Unity when trying to get data from a static class

I'm working on the save system for a local co-op game I'm working on. The goal of the code is to establish a Serializable Static class that has instances of the four players and the relevant data they need to store for saving in binary.

[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;
    }
}

The Player Class just contains the ints that track player stats and a bool for if they are in the alive state or not. My issue comes when one of my classes in the game scene needs to get data from this static class. When the static class is referenced, it throws the error.

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

I am new to coding so I'm not sure how Unity interacts with static classes that don't inherit from MonoBehaviour . I based this code off of a tutorial that worked pretty similarly, so I'm not sure what the issue is.

Nothing is initialising current .

One quick solution is to initialise current like this:

 public static GameState current = new GameState();

This is the Singleton pattern, you can read a about it all over the web, but this post by Jon Skeet is a fairly decent place to start.

I'd consider making the GameState constructor private, and making current (aka Instance normally) into a property with only a getter:

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

There are many more ways to do this, especially if multi-threading is a concern, then you should read the Jon Skeet post.

To give another perspective: If you want to implement that as a static class, then this works differently, starting from referencing the class and its data and not ending with the constructor:

 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() {
[...]

Of course your methods would reference this static class' static data different now too:

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

If you want a (serializable!) Singleton - see DaveShaws answer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM