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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

NullReferenceException

Discussion in 'Scripting' started by TheJumpah, Jan 9, 2020.

  1. TheJumpah

    TheJumpah

    Joined:
    Nov 2, 2019
    Posts:
    6
    Hello, so I'm not the most "advanced" programmer as I'm teaching myself but I am working on a project and I'm currently attempting to design a combat system. I created an empty game object and placed a script on it for tracking how combat damage is handled. What I was looking to do is create this script and then have all my heroes use the script to take damage. I created a reference to the combat script on my heroes script expecting it to work and my character would take damage using the update function and an input.getkeydown. However it isn't working and I'm receiving a NullReferenceException anyone know why and how to fix this? I've provided both scripts below.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CombatManager : MonoBehaviour
    6. {
    7.     public Heroes heroes;
    8.     float armorResistance;
    9.     float magicResistance;
    10.  
    11.     public void Awake()
    12.     {
    13.         heroes = GetComponent<Heroes>();
    14.  
    15.     }
    16.  
    17.  
    18.  
    19.     public void TakeDamage(float attackDMG)
    20.     {
    21.         heroes.maxHealth -= heroes.attackDMG;
    22.         armorResistance = 100 / (100 + heroes.armor);
    23.         if (heroes.armor > 0)
    24.         {
    25.             heroes.maxHealth -= heroes.attackDMG * armorResistance;
    26.             Debug.Log("takes dmg");
    27.         }
    28.  
    29.  
    30.  
    31.  
    32.     }
    33.  
    34.     public void MagicDamage(float abilityPOWER)
    35.     {
    36.         heroes.maxHealth -= heroes.abilityPOWER;
    37.         magicResistance = 100 / (100 + heroes.magicResist);
    38.         if(heroes.magicResist > 0)
    39.         {
    40.             heroes.maxHealth -= heroes.abilityPOWER * magicResistance;
    41.         }
    42.  
    43.  
    44.     }
    45.  
    46.    
    47. }
    48.  
    49.  
    50.  
    51.  
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Heroes : MonoBehaviour
    6. {
    7.     public Hero hero;
    8.     private CombatManager combatManager;
    9.     public float maxHealth;
    10.     public float mana;
    11.     public float attackDMG;
    12.     public float abilityPOWER;
    13.     public float armor;
    14.     public float magicResist;
    15.     public float attackSpeed;
    16.     public float cooldown;
    17.     public float critical;
    18.     void Start()
    19.     {
    20.         maxHealth = hero.Health;
    21.         mana = hero.mana;
    22.         attackDMG = hero.attackDmg;
    23.         abilityPOWER = hero.abilityPower;
    24.         armor = hero.armor;
    25.         magicResist = hero.magicResist;
    26.         attackSpeed = hero.attackSpeed;
    27.         cooldown = hero.cooldown;
    28.         critical = hero.criticalStrike;
    29.         combatManager = GetComponent<CombatManager>();
    30.  
    31.     }
    32.  
    33.     private void Update()
    34.     {
    35.         if (Input.GetKeyDown(KeyCode.J))
    36.         {
    37.             combatManager.TakeDamage(200);
    38.  
    39.         }
    40.     }
    41.  
    42.  
    43.     void PlayerGrowth()
    44.     {
    45.  
    46.     }
    47. }
    48.  
     

    Attached Files:

  2. Karrzun

    Karrzun

    Joined:
    Oct 26, 2017
    Posts:
    123
    GetComponent only finds Component on the same GameObject, but it sounds like your scripts are attached to different ones. In that case, you'd have to make a reference to the GameObject your CombatManager is attached to first and then call GetComponent<CombatManager>() on that.
     
  3. TheJumpah

    TheJumpah

    Joined:
    Nov 2, 2019
    Posts:
    6
    Do you mean like this? If so how do I call functions from the script like this? Do I have to type out the full second line of code each time I want to use a function from it?
    Code (CSharp):
    1.  GameManager = GameObject.FindGameObjectWithTag("Manager");
    2.         GameManager.GetComponent<CombatManager>();
     
  4. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    You can store a reference to the component returned by GetComponent:
    Code (csharp):
    1. GameManager = GameObject.FindGameObjectWithTag("Manager");
    2. CombatManager cm = GameManager.GetComponent<CombatManager>();
    3. // ...
    4. cm.SomeMethod();
    5. // ...
    6. cm.SomeOtherMethod(someParam);
     
  5. adi7b9

    adi7b9

    Joined:
    Feb 22, 2015
    Posts:
    181
    Like WallaceT_MFM said. I should add a check if is null before using cm.
    Code (CSharp):
    1. if (cm != null)
    2. {
    3. ...
    4. }
    In your first post, maybe the variable "heroes" is null.

    The damage system is quite simple:
    You have 1 script, for creatures and for player:
    Code (CSharp):
    1. class DamageClass
    2. {
    3.    int HP;
    4.  
    5.    public void TakeDamage(int value)
    6.    {
    7.       HP -= value; // check if HP <= 0
    8.    }
    9.  
    10. };
    In your code, when you know the enemy (you need to know the enemy):
    1. for the player an enemy is a creature
    2. for a creature an enemy is the player

    Code (CSharp):
    1. GameObject enemy = ... // you need to know this
    2.  
    3. DamageClass scrpt = enemy.GetComponent<DamageClass>();
    4.  
    5. if (scrpt != null)
    6. {
    7.    scrpt.TakeDamage(10);
    8. }
    For creatures is easy to set the enemy (in single player mode) because.. it's you.