Saving a List of variables between scenes

I am making a small airport simulator, for that I have three scenes that i jump back and forth between (three menus so to speak). One of these is an interactive map where you can assign flight routes, however, when I change to another menu my flight routes has been deleted because unity clears all objects.

So I sat up a controller object which uses the “DoNotDestroyOnLoad” method which is quite handy, however, every flight is represented by a small plane, which also stores all the relevant flight data. (Using DoNotDestroyOnLoad on each plane is not that smart as they will then appear in the other menus) - I store these flights as a list of gameobjects in the controller object - but to no surprise all the gameojects are missing when you change scene and change back again - SO i made another list that contains a variables instead of gameobjects. These variables are a custom script that contain all the relevant data for a flight route, and then I store that. If I then try to instantiate planes from this list it works fine, however, if I change scene and go back again, it tells me that I get a NullReferenceExpectation - which is annoying because that means the list of variables are being cleared every time I change scene - how do I prevent that from happening? :open_mouth:

Here is my controller script:

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

public class controllerScript : MonoBehaviour {

	private static bool created = false;
	public GameObject smallPlanes;
	public GameObject mediumPlanes;
	public GameObject largePlanes;
	public bool instansiated = false;

	public List<GameObject> flights;
	public List<AirplaneClassScript> temp;
	void Awake(){
		if (!created) {
			// this is the first instance - make it persist
			DontDestroyOnLoad(this.gameObject);
			created = true;
		} else {
			// this must be a duplicate from a scene reload - DESTROY!
			Destroy(this.gameObject);
		} 
	}

	void Start(){
		flights = new List<GameObject>();
		temp = new List<AirplaneClassScript>();
	}

	public void instantiatePlanes(){
		foreach(AirplaneClassScript planeTemp in temp){
			GameObject newPlane;
			switch(planeTemp.type){ // <--- here it gives me a nullref error
			case("small"):
				newPlane = (GameObject)Instantiate(smallPlanes);
				break;
			case("medium"):
				newPlane = (GameObject)Instantiate(mediumPlanes);
				break;
			case("large"):
				newPlane = (GameObject)Instantiate(largePlanes);
				break;
			}
		}
	}
}

Here is my variable script which stores everything that is relevant for the flight:

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

public class AirplaneClassScript : MonoBehaviour {

	public string type;
	public int maxPax, maxCargo, travelCost, speed;
	public List<string> route;
	public bool pax, cargo, mix;
	
	public int FH;
	public int startTurn;

	public Vector3 currentPosition;

	void Awake(){
		DontDestroyOnLoad(this.gameObject);
	}

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

Thanks a lot in advance! :slight_smile:

Thanks for the reply, I will adress your points in the same structure :slight_smile:

  1. Good point, yes it just contains data, so it is silly to make it derive from monobehaviour :slight_smile: thanks for pointing that out.

  2. I do that through another script, it is quite long but here is the relevant part, which also answers your last question

    case(“Map”):
    if(GUI.Button(new Rect(Screen.width - 65, 15, 50, 50), “X”)){
    GameObject.FindGameObjectWithTag(“controller”).GetComponent().instantiatePlanes();
    }
    if(!GameObject.FindGameObjectWithTag(“controller”).GetComponent().instansiated){
    GameObject.FindGameObjectWithTag(“controller”).GetComponent().instantiatePlanes();
    GameObject.FindGameObjectWithTag(“controller”).GetComponent().instansiated = true;
    }
    if(GUI.Button(new Rect(15.0f, 15.0f, 100.0f, 25.0f), “Small Planes”)){
    flightOption = true;
    controllerScript controlScript = GameObject.FindGameObjectWithTag(“controller”).GetComponent();
    newPlane = (GameObject)Instantiate(smallPlane);
    newPlaneTemp = new AirplaneClassScript();
    controlScript.flights.Add(newPlane);
    controlScript.temp.Add (newPlaneTemp);
    newPlaneTemp.type = newPlane.tag;
    newPlaneTemp.startTurn = newPlane.GetComponent().startTurn;
    }
    if(GUI.Button(new Rect(15.0f, 45.0f, 100.0f, 25.0f), “Medium Planes”)){
    flightOption = true;
    controllerScript controlScript = GameObject.FindGameObjectWithTag(“controller”).GetComponent();
    newPlane = (GameObject)Instantiate(mediumPlane);
    newPlaneTemp = new AirplaneClassScript();
    controlScript.flights.Add(newPlane);
    controlScript.temp.Add (newPlaneTemp);
    newPlaneTemp.type = newPlane.tag;
    }
    if(GUI.Button(new Rect(15.0f, 75.0f, 100.0f, 25.0f), “Large Planes”)){
    flightOption = true;
    controllerScript controlScript = GameObject.FindGameObjectWithTag(“controller”).GetComponent();
    newPlane = (GameObject)Instantiate(largePlane);
    newPlaneTemp = new AirplaneClassScript();
    controlScript.flights.Add(newPlane);
    controlScript.temp.Add (newPlaneTemp);
    newPlaneTemp.type = newPlane.tag;
    }
    if(flightOption){
    GUI.Box(new Rect(Screen.width/2 - 125, Screen.height/2 - 75, 250, 150), “Select Type”);
    if(GUI.Button(new Rect(Screen.width/2 - 50, Screen.height/2 - 30, 100, 25), “PAX”)){
    newPlane.GetComponent().pax = true;
    newPlaneTemp.pax = true;
    flightOption = false;
    routeOption = true;
    }
    if(GUI.Button(new Rect(Screen.width/2 - 50, Screen.height/2, 100, 25), “Cargo”)){
    newPlane.GetComponent().cargo = true;
    newPlaneTemp.cargo = true;
    flightOption = false;
    routeOption = true;
    }
    if(GUI.Button(new Rect(Screen.width/2 - 50, Screen.height/2 + 30, 100, 25), “Mix”)){
    newPlane.GetComponent().mix = true;
    newPlaneTemp.mix = true;
    flightOption = false;
    routeOption = true;
    }
    }
    if(routeOption){
    if(GUI.Button(new Rect( Screen.width/2 - 125, 50, 100, 50), “Complete Route”)){
    print (“complete route”);
    newPlane.transform.position = new Vector3(GameObject.Find(newPlane.GetComponent().route[0]).transform.position.x, GameObject.Find(newPlane.GetComponent().route[0]).transform.position.y, -2);
    newPlaneTemp.currentPosition = newPlane.transform.position;
    newPlaneTemp.route = newPlane.GetComponent().route;
    routeOption = false;
    newPlane = null;
    newPlaneTemp = null;
    }
    if(GUI.Button(new Rect( Screen.width/2 + 25, 50, 100, 50), “Cancel”)){
    controllerScript controlScript = GameObject.FindGameObjectWithTag(“controller”).GetComponent();
    controlScript.flights.Remove(newPlane);
    controlScript.temp.Remove(newPlaneTemp);
    Destroy(newPlane);
    newPlane = null;
    newPlaneTemp = null;
    routeOption = false;
    }
    }
    break;
    }

This code is handling the GUI of the game, and it is through here that the function calls comes.

  1. something else populates it, but do you mean to say it is clearing itself on every start()? I guess it does, but if it does - but then again in the inspector it does state it has the correct number of variables stored, just that they are missing. (well for gameObjects it states missing, for variables it does not state so)

UPDATE!

making the variable script just a script, meaning I do not derive from monoBehaviour seems to have fixed the problem :slight_smile: thanks a lot for the help :slight_smile: