Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Getting null reference even with getComponent<>

Discussion in 'Scripting' started by clerkburton, Oct 22, 2022.

  1. clerkburton

    clerkburton

    Joined:
    Sep 15, 2017
    Posts:
    3
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class StatManager : MonoBehaviour
    6. {
    7.     [Header("Character Stat")]
    8.     [SerializeField] float HP;
    9.     [SerializeField] float stamina;
    10.  
    11.     public float statMan_getHP() { return HP; }
    12.     public float statMan_getStamina() { return stamina; }
    13.  
    14. }
    I made a stat manager script and add it to a game object(Stat Manager) on the scene.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Character_info: MonoBehaviour
    6. {
    7.    [Header("Character Stat")]
    8.     [SerializeField] StatValue HP;
    9.     [SerializeField] StatValue stamina;
    10.  
    11.     StatManager sm;
    12.  
    13.     private void Start()
    14.     {
    15.         sm = gameObject.GetComponent<StatManager>();
    16.  
    17.         HP.equalToValue(sm.statMan_getHP());
    18.         stamina.equalToValue(sm.statMan_getStamina());
    19.      }
    20. }
    And this script is added to my character(prefab) but when i spawn this character prefab, I get null reference not set to an instance of an object. So I'm assuming that my gameobject sm is null!? If so, how can I get my sm to reference the game object(Stat Manager)? My Stat Manager is not a prefab.

    I tried:
    1. turning my stat manager into a prefab
    2. sm = sm.GetComponent<StatManager>();

    or a combination of both but none worked.
     
    Last edited: Oct 22, 2022
  2. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    The line
    sm = gameObject.GetComponent<StatManager>();
    means "give me the StatManager component that is on the same game object as the Character_info component. Now, you've said that your StatManager component is actually on some other game object in the scene, so it isn't on the same game object as the Character_info component.

    You can resolve this situation in a number of ways. Since this is taking place in the start method, I suggest that you do a quick search for the StatManager game object before trying to get its component.

    Change your start to this:
    Code (CSharp):
    1. private void Start()
    2. {
    3.     sm = GameObject.FindObjectOfType<StatManager>();
    4.     HP.equalToValue(sm.statMan_getHP());
    5.     stamina.equalToValue(sm.statMan_getStamina());
    6. }
    This will look for an object with the StatManager component anywhere in the scene. If it finds one or more, it'll put a reference to the first one it finds in the sm field.
     
  3. clerkburton

    clerkburton

    Joined:
    Sep 15, 2017
    Posts:
    3
    I was thinking of using FindObjectOfType as well but my game is gonna spawn Character NPCs(Using Character_Info) and some other game objects in real time from time to time, will this tank the performance!?
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    You might want to look at scriptable objects instead if you want a way to define the stats and characteristics of NPCs and other entities. It's pretty easy to make an SO that outlines some parameters then copy that into a monobehaviour on Awake/OnEnable.

    Basic example:
    Code (CSharp):
    1. [System.Serializable]
    2. public struct CharacterStats
    3. {
    4.     public float Health;
    5.     public float Stamina;
    6. }
    7.  
    8. [CreateAssetMenu(menuName = "Entities/Character Stats")]
    9. public class CharacterStatsObject : ScriptableObject
    10. {
    11.     [SerializeField]
    12.     private CharacterStats characterStats;
    13.    
    14.     public CharacterStats CharacterStats => characterStats;
    15. }
    16.  
    17. public class CharacterComponent : Monobehaviour
    18. {
    19.     [SerializeField]
    20.     private CharacterStatsObject statsObject;
    21.    
    22.     private CharacterStats characterStats;
    23.    
    24.     private void Awake()
    25.     {
    26.         if (statsObject)
    27.         {
    28.             characterStats = statsObject.CharacterStats;
    29.         }
    30.     }
    31. }
    If you're not familiar with scriptable objects, lots of resources out there on how to use them.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,750
    The above random actions makes me think you have not yet accomplished the FIRST STEP of fixing a null reference.

    Keep in mind the only three steps to fix null references and those steps are ALWAYS the same.

    How to fix a NullReferenceException error

    https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

    Three steps to success:
    - Identify what is null <-- any other action taken before this step is WASTED TIME
    - Identify why it is null
    - Fix that