Search code examples
c#unity-game-engineinstancegameobject

How can I access a public variable from an Instance of an object?


I currently have a GameMaster object which I am using to save stats through transitioning scenes. One of the fields that I'm storing is the playerMaxHealth value. I am attempting to load this value into the Player object in the playerStats.MaxHealth value at the beginning of every scene. At this point my GameMaster instantiation is working perfectly and the values are being saved from scene to scene, but I am having trouble accessing the playerMaxHealth value from the newly loaded Player object. I've tried numerous things, including solutions on this site, and I am never able to access this object. I've included the code from my current attempt, in the form of both scripts, as well as the current error message (its changed with every different method I try). What is the correct way of accessing this value and loading it into the Player playerStats.MaxHealth value?

GAMEMASTER:

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

    public class GameMaster : MonoBehaviour
    {
        public static GameMaster Instance;    

        public static int playerLevel = 1;
        public static int playerExp = 0;
        public static int expTilNextLevel = 1000;
        public static int playerMaxHealth = 100;


        void Awake () {
            if (Instance == null) {
                DontDestroyOnLoad(gameObject);
                Instance = this;
            }
            else if (Instance != this){
                Destroy (gameObject);
            }
        }

        void Update() {
            if(Input.GetKeyDown(KeyCode.L)){
                AddExp();
            }

            if(Input.GetKeyDown(KeyCode.H)){
                //Player.DamagePlayer(10);
            }
        }

        public static void KillPlayer (Player player) {
            Destroy (player.gameObject);
        }

        public static void KillEnemy (Enemy enemy) {
            Destroy (enemy.gameObject);
            AddExp();
        }

        private static void AddExp () {
            playerExp += 100;
            if (playerExp >= expTilNextLevel) {
                playerLevel++;
                playerExp = playerExp - expTilNextLevel;
                expTilNextLevel = (int)((float)expTilNextLevel * 1.5f);
            } 
            Debug.Log("Player Exp: " + playerExp + "/" + expTilNextLevel + "   Player Lvl: " + playerLevel);
        }

    }

PLAYER:



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

    public class Player : MonoBehaviour
    {

        [System.Serializable]
            public class PlayerStats {
            public int MaxHealth = 100;
            public int Health = 100;
            public int Exp = 0;
            public int Strength = 1;
        }

        public PlayerStats playerStats = new PlayerStats();


        void Start() {
            GameObject gameMaster = GameObject.FindWithTag("GameMaster") as GameObject;
            playerStats.MaxHealth = gameMaster.playerMaxHealth;
            Debug.Log("Player Max Health: ");
        }


        public void DamagePlayer(int damage){
            playerStats.Health -= damage;
            if (playerStats.Health <= 0) {
                GameMaster.KillPlayer(this);
                Debug.Log ("YOU DIED");
            }
        }

    }

Error message: 'GameObject' does not contain a definition for 'playerMaxHealth' and no accessible extension method 'playerMaxHealth' accepting a first argument of type 'GameObject' could be found (are you missing a using directive or an assembly reference?)


Solution

  • If GameMaster is a component that is attached to the GameObject, then playerMaxHealth is a property of that component and not the GameObject.

    What you want to do is get the component itself so that you can access the member variable.

    eg:

    GameMaster gameMasterComponent = gameMaster.GetComponent<GameMaster>();
    
    playerStats.MaxHealth = gameMasterComponent.playerMaxHealth;
    

    Alternately, since you are treating GameMaster as a singleton, and playerMaxHealth is static, either of the following should also work:

    // as singleton 
    playerStats.MaxHealth = GameMaster.Instance.playerMaxHealth;
    
    // as static property
    playerStats.MaxHealth = GameMaster.playerMaxHealth;