0
\$\begingroup\$

I'm getting a null reference exception on "AddEmpireView()" and I cannot figure it out for the life of me. Here's the class:

namespace CovertGalaxia
{

public class AgentList // Wrapper for the GalaxyDB loading mechanism.
{
    public List<Agent> agents = new List<Agent>();
}

[System.Serializable]
public class Agent
{
    public int AgentIndex = -1;
    public string AgentName;
    public string Affiliation;
    public int Empire;
    public string PersonalityType; 
    public int Command;
    public int Observation;
    public int Violence;
    public int Espionage;
    public int Reputation;
    public int Treachery;
    public bool Recruited;
    public IDictionary<int, EmpireAgentView> EmpireViews = new Dictionary<int, EmpireAgentView>();

    public int ArrivalDate;
    public int ColonyIndex; 

    public string MugShot;
    public string Bio;

    public Agent(int newAgentIndex, string newAgentName, string newAffiliation, int newEmpire, string newPersonalityType, int newCommand, int newObservation, int newViolence, int newEspionage, int newReputation, int newTreachery, int newArrivalDate, int newLocation, string newBio, string newMugshot)
    {
        AgentIndex = newAgentIndex;
        AgentName = newAgentName;
        Affiliation = newAffiliation;
        Empire = -1; 
        PersonalityType = newPersonalityType;
        Command = newCommand;
        Observation = newObservation;
        Violence = newViolence;
        Espionage = newEspionage;
        Reputation = newReputation;
        Treachery = newTreachery;
        ArrivalDate = newArrivalDate;
        ColonyIndex = newLocation;
        MugShot = newMugshot;
        Bio = newBio;
        Recruited = false;
    }

    public void UpdateEmpireView(int empireIndex)
    {

        EmpireViews[empireIndex].AgentName = this.AgentName;
        EmpireViews[empireIndex].AgentIndex = this.AgentIndex;
        EmpireViews[empireIndex].ArrivalDate = this.ArrivalDate;
        EmpireViews[empireIndex].ColonyIndex = this.ColonyIndex;

    }

    public void AddEmpireView()
    {
        foreach (Empire e in UniverseManager.Instance.Galaxy.GetEmpires())
        {
            Debug.Log("Empire: " + e.EmpireIndex);
            this.EmpireViews.Add(e.EmpireIndex, new EmpireAgentView());
        }
    }

    public EmpireAgentView ShowEmpireView(int eIndex)
    {
        if (EmpireViews.ContainsKey(eIndex))
        {
            EmpireAgentView e = EmpireViews[eIndex];
            return e;
        }
        return new EmpireAgentView();
    }

}

[System.Serializable]
public class EmpireAgentView
{
    public string AgentName = "Nobody";
    public int AgentIndex = -1;
    public int ArrivalDate = -1;
    public int ColonyIndex = -1;
    public int Empire = -1;

}
}

I've made sure that the e.EmpireIndex is a populated field (if I comment out the add line then the debug log successfully lists four different numbers). I'm so confused.

UPDATE: Thanks to @Brian and @rbwhitaker in the comments, I've been able to figure out that the issue is serialization. Unity's JSON Utility does not support dictionaries (https://answers.unity.com/questions/1185613/how-can-i-save-a-dictionary-in-a-class-to-json.html). I'm trying to load the list of agents with partial info from a JSON file, and then add extra data as defined by my Agent class.

Here's an example of what my JSON file looks like:

{
    "agents": [
        {
              "AgentIndex": 0,
              "AgentName": "Nines",
              "Affiliation": "CLI",
              "PersonalityType": "Aggressive",
              "Command": 20,
              "Observation": 15,
              "Violence": 10,
              "Espionage": 18,
              "Reputation": 12,
              "Treachery": 6,
              "ArrivalDate": 0,
              "Location": 0,
              "MugShot": null,
              "Bio": "Admiral Nines is the foremost commander of special forces in your fleet."
        }
    ]
}

UPDATE: I am still very confused by this whole thing. Not sure if it helps, but here's the file that's loading the data from JSON:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace CovertGalaxia
{
    static class GalaxyDB
    {

        public static string json = JsonUtility.ToJson(NumPlayers);

        public static string LoadFile(string path)
        {

            string filePath = path.Replace(".json", "");

            TextAsset targetFile = Resources.Load<TextAsset>(filePath);

            return targetFile.text;
        }

        public static List<Agent> agents;
        public static AgentList agentsdb;

        public static void LoadData()
        {
            string agentPath = Application.dataPath + "/Resources/AgentDB.json";


            if (File.Exists(agentPath))
            {
                string agentsdataAsJson = File.ReadAllText(agentPath);
                agentsdb = JsonUtility.FromJson<AgentList>(agentsdataAsJson);
                agents = agentsdb.agents;

            }
            else
            {
                Debug.LogError("FAILED TO LOAD AGENTDATA");
            }
        }

    }
}
\$\endgroup\$
6
  • 2
    \$\begingroup\$ Is your EmpireViews dictionary null? Your class is marked serializable, so is it possible that is not being set and getting serialized to null? \$\endgroup\$
    – Brian
    Jan 4, 2020 at 4:29
  • 1
    \$\begingroup\$ I suspect @Brian is on to something. That field normally wouldn't be null, but in this case, if the object is being deserialized, your normal field initializer is not going to run as expected. It's the way serialization is done. No field or property initializers and no constructor. Is this object being created through deserialization? \$\endgroup\$
    – rbwhitaker
    Jan 4, 2020 at 5:17
  • \$\begingroup\$ @rbwhitaker Alright, you are indeed on to something. I removed the serializable and It stopped giving me a null reference exception. But I need it serializable in order to load the database from a JSON file (apparently?). So are you saying the problem isn't in the class but in how the class is being created? \$\endgroup\$ Jan 4, 2020 at 7:46
  • \$\begingroup\$ Learning as I go here :) So yes, I load the list of Agents from a JSON file. That database does NOT have anything listed for the dictionary. So, do I need to add the dictionary to the JSON file somehow? Is there any way I can create these EmpireAgentView's without having to add it to the JSON? \$\endgroup\$ Jan 4, 2020 at 8:52
  • \$\begingroup\$ @rbwhitaker, am I at least on the right track? I feel a little lost in the weeds here trying to understand serialization and dictionaries and why this isn't working. I tried switching it to an array and it doesn't like that either. I'm pretty confused at this point. \$\endgroup\$ Jan 6, 2020 at 8:14

0

You must log in to answer this question.

Browse other questions tagged .