NullReferenceException

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.

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

public class CombatManager : MonoBehaviour
{
    public Heroes heroes;
    float armorResistance;
    float magicResistance;

    public void Awake()
    {
        heroes = GetComponent<Heroes>();

    }

  

    public void TakeDamage(float attackDMG)
    {
        heroes.maxHealth -= heroes.attackDMG;
        armorResistance = 100 / (100 + heroes.armor);
        if (heroes.armor > 0)
        {
            heroes.maxHealth -= heroes.attackDMG * armorResistance;
            Debug.Log("takes dmg");
        }




    }

    public void MagicDamage(float abilityPOWER)
    {
        heroes.maxHealth -= heroes.abilityPOWER;
        magicResistance = 100 / (100 + heroes.magicResist);
        if(heroes.magicResist > 0)
        {
            heroes.maxHealth -= heroes.abilityPOWER * magicResistance;
        }


    }

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

public class Heroes : MonoBehaviour
{
    public Hero hero;
    private CombatManager combatManager;
    public float maxHealth;
    public float mana;
    public float attackDMG;
    public float abilityPOWER;
    public float armor;
    public float magicResist;
    public float attackSpeed;
    public float cooldown;
    public float critical;
    void Start()
    {
        maxHealth = hero.Health;
        mana = hero.mana;
        attackDMG = hero.attackDmg;
        abilityPOWER = hero.abilityPower;
        armor = hero.armor;
        magicResist = hero.magicResist;
        attackSpeed = hero.attackSpeed;
        cooldown = hero.cooldown;
        critical = hero.criticalStrike;
        combatManager = GetComponent<CombatManager>();

    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            combatManager.TakeDamage(200);

        }
    }


    void PlayerGrowth()
    {

    }
}

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() on that.

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?

 GameManager = GameObject.FindGameObjectWithTag("Manager");
        GameManager.GetComponent<CombatManager>();

You can store a reference to the component returned by GetComponent:

GameManager = GameObject.FindGameObjectWithTag("Manager");
CombatManager cm = GameManager.GetComponent<CombatManager>();
// ...
cm.SomeMethod();
// ...
cm.SomeOtherMethod(someParam);

Like WallaceT_MFM said. I should add a check if is null before using cm.

if (cm != null)
{
...
}

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:

class DamageClass
{
   int HP;

   public void TakeDamage(int value)
   {
      HP -= value; // check if HP <= 0 
   }

};

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
GameObject enemy = ... // you need to know this

DamageClass scrpt = enemy.GetComponent<DamageClass>();

if (scrpt != null)
{
   scrpt.TakeDamage(10);
}

For creatures is easy to set the enemy (in single player mode) because… it’s you.