3
votes

[Picture]I am developing a game and am trying to make a save and load button. I believe that I have coded correctly, but my problem is that the player that I wish to access does not get found. I suspect that it has something to do with the way I am coding it.

Due to having multiple levels I have used the code: GameObject player = GameObject.FindWithTag("Player"); to try and find the given player in the scene, but I do not think it is working.

I did not set the player as a public variable as it changes throughout each scene.

For example, I have attempted to access the players current health with the following lines of code, which is saved in a GameController empty game object in a script called Gamecontrol.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using UnityEngine.SceneManagement;

public class GameControl : MonoBehaviour {
    public static GameControl controller;
    int shooterHealth;
    int shooterScore;
//public GameObject player;
//public GameObject gun;
    int level;

// Use this for initialization
    void Awake() {
        GameObject player = GameObject.FindWithTag("Player");
        shooterHealth = player.GetComponent<PlayerHealth>().currentHealth;
        shooterScore = player.GetComponent<Gun>().score;
        level = player.GetComponent<PlayerHealth>().level;


        if(controller == null) {
            DontDestroyOnLoad(gameObject);
            controller = this;
        }
        else if(controller != this) {
            Destroy(gameObject);
        }

    }
    public void SaveGame() {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create(Application.persistentDataPath +     "/shooter.dat");

        PlayerData data = new PlayerData();
        data.shooterHealth = shooterHealth;
        data.shooterScore = shooterScore;
        data.level = level;
        bf.Serialize(file, data);
        file.Close();
    }

    public void LoadGame() {
        if(File.Exists(Application.persistentDataPath + "/shooter.dat")) 
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.persistentDataPath +     "/shooter.dat", FileMode.Open);
            PlayerData data = (PlayerData)bf.Deserialize(file);

            file.Close();


            GameObject player = GameObject.FindWithTag("Player");
            player.GetComponent<PlayerHealth>().currentHealth = data.shooterHealth;
            player.GetComponent<Gun>().score = data.shooterScore;
            level = player.GetComponent<PlayerHealth>().level;
            SceneManager.LoadScene(level);




        }
    }


}
[Serializable]
class PlayerData
{
    public int shooterHealth;
    public int shooterScore;
    public int level;
}

The error that I get is:

NullReferenceException: Object reference not set to an instance of an object GameControl.Awake () (at Assets/GameControl.cs:20)

Does anybody know a way around this? Thank you in advance:)

1
Are you sure the player is tagged correctly? - Ali Kanat
Yes I am sure, I even tried changing the tags to different ones and it says the same error:( - Naeem Dogar
Well that is strange. Can you share full script maybe you are doing something wrong in other parts of the code - Ali Kanat
Also is the player active in the scene? If not then you can not find it. - Ali Kanat
I have updated a picture:) - Naeem Dogar

1 Answers

0
votes

The error is in shooterScore = player.GetComponent<Gun>().score; You are trying to access the component Gun, but the Player GameObject doesn't have a Gun component attached. Maybe your forgot to attach it or you it has another name.

Maybe you attach the Gun component at runtime. In that case check the script execution order to verify that the GameControl script is executed after the script that attaches the Gun component at runtime.