I am trying to make it so that when the player is selecting a ship, it will check an array of boolean values to see if the specific ship is unlocked, but it keeps giving me a NullReferenceException saying that the Object Reference is not set to an instance of an object.
I’m able to get other values from the script I’m accessing, but not the bool array.
Here’s the ship selecting script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ShipSelect : MonoBehaviour {
public LoadScene loader;
public Sprite[] shipSelect;
public Image shipImage;
public Image lockedImage;
public Text shipText;
public int shipNum = 0;
public bool unlocked = true;
public AudioSource source;
public AudioClip fail;
// Use this for initialization
void Start ()
{
}
public void ChangeShip (int l_or_r)
{
// Add or subtract to shipNum based on which button is clicked
shipNum += l_or_r;
if (shipNum < 0) {
// If shipNum is less than 0, loop to the last value
shipNum = shipSelect.Length - 1;
} else if (shipNum > shipSelect.Length - 1) {
// If shipNum passes the last value, loop back to 0
shipNum = 0;
}
// Check if the related ship is unlocked in GameData
unlocked = GameData.data.unlocks [shipNum];
shipImage.sprite = shipSelect [shipNum];
if (unlocked != true) {
// If not, enable the lock image over the ship sprite
lockedImage.enabled = true;
} else if (unlocked == true) {
// Otherwise remove it
lockedImage.enabled = false;
}
// Set the text to be the name of the ship
if (shipNum == 0) {
shipText.text = "Basic";
} else if (shipNum == 1) {
shipText.text = "Tri";
} else if (shipNum == 2) {
shipText.text = "TenK";
}
}
public void SelectedShip ()
{
if (unlocked == true)
{
// If current ship is unlocked, play click sound and load the Game scene
source.Play ();
loader.LoadByIndex (1);
}
else
{
// If locked, play an error sound
source.PlayOneShot (fail);
}
}
}
And here’s the GameData script (sorry it’s probably a mess, this is my first project):
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class GameData : MonoBehaviour {
public static GameData data;
GameObject shipControl;
public int shipNum;
bool init = false;
public GameObject ui;
[HideInInspector] public Text scoreText, lifeText;
[HideInInspector] public int highScore, deaths, asteroids_destroyed, buttroids_destroyed;
public bool[] unlocks = new bool[8];
[HideInInspector] public int go_score, life_score;
int score;
public int lives;
Scene currentscene;
void Awake ()
{
if (data == null)
{
DontDestroyOnLoad (gameObject);
data = this;
}
else if (data != this)
{
Destroy (gameObject);
}
unlocks [0] = true;
}
void Start ()
{
score = 0;
lives = 3;
}
void AddScore (int points)
{
if (points == 50) {
asteroids_destroyed += 1;
} else {
buttroids_destroyed += 1;
}
score = score + points;
if (score >= highScore) {
highScore = score;
}
}
void LoseLife ()
{
lives -= 1;
deaths += 1;
// Gets highest score in a single life
if (score > life_score) {
life_score = score;
}
// Sets end score and sends everything to game over screen
if (lives <= 0)
{
go_score = score;
GameOver();
}
}
void Update ()
{
if (init == true) {
// If ui is loaded, update it each frame
scoreText.text = "Score: " + score;
lifeText.text = "Lives: " + lives;
} else {
// Check if Game scene is loaded
currentscene = SceneManager.GetActiveScene ();
if (currentscene.name == "Game") {
// Load ui and get it ready for updating
ui = GameObject.FindGameObjectWithTag ("GameUI");
scoreText = ui.GetComponentsInChildren<Text> () [0];
lifeText = ui.GetComponentsInChildren<Text> () [1];
init = true;
}
}
if (Input.GetKey ("a") && Input.GetKey ("s") && Input.GetKey ("d") && Input.GetKey ("f")) {
highScore = 0;
Debug.Log ("Highscore reset");
}
}
void GameOver ()
{
init = false;
SceneManager.LoadScene (2);
}
public void OnEnable ()
{
if (File.Exists (Application.persistentDataPath + "/Data.dat"))
{
BinaryFormatter bf = new BinaryFormatter ();
FileStream save_file = File.Open (Application.persistentDataPath + "/Data.dat", FileMode.Open);
SaveData data = (SaveData)bf.Deserialize (save_file);
save_file.Close ();
highScore = data.Highscore;
deaths = data.deaths;
asteroids_destroyed = data.asteroids_destroyed;
buttroids_destroyed = data.buttroids_destroyed;
unlocks = data.unlocks;
}
}
public void OnDisable ()
{
BinaryFormatter bf = new BinaryFormatter ();
FileStream save_file = File.Create (Application.persistentDataPath + "/Data.dat");
SaveData data = new SaveData ();
data.Highscore = highScore;
data.deaths = deaths;
data.asteroids_destroyed = asteroids_destroyed;
data.buttroids_destroyed = buttroids_destroyed;
data.unlocks = unlocks;
bf.Serialize (save_file, data);
save_file.Close ();
}
}
[Serializable]
class SaveData
{
public int Highscore, deaths, asteroids_destroyed, buttroids_destroyed;
public bool[] unlocks;
}
Anyways, any ideas would be helpful, the stuff works it I set the bool manually, but I can’t seem to get it from the array, and I don’t understand why (Though if I had to guess, it’d be because of the variable for the array, but it works for me in other scripts?).
I suppose I could just check the unlock conditions each time if I can’t figure this out, but I feel like I’m just missing something simple…