-1

Does anyone know why im getting this error?

Object reference not set to an instance of an object HealthBar.TakeDamage (System.Int32 damage) (at Assets/Scripts/HealthBar.cs:61) HealthBar.Update () (at Assets/Scripts/HealthBar.cs:36)

the code seems to work as intended when i try to run "TakeDamage()" but i recieve that error after it executes even though its giving me the correct behavior.

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

public class HealthBar : MonoBehaviour
{
    public CharacterStats stats;
    public Slider slider;

    
    // Start is called before the first frame update
    void Start()
    {
        slider.value = slider.maxValue;
    }

    // Updates the Current Hp Text
    public Text valueText;

    public void OnSliderChanged(float value)
    {
        valueText.text = value.ToString();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            HealDamage(30);
            Debug.Log("Space");
        }
        if (Input.GetKeyDown(KeyCode.E))
        {
            TakeDamage(10);
            Debug.Log("E");
        }
        if (Input.GetKeyDown(KeyCode.Q))
        {
            TempMaxHealth(5f,20);
            Debug.Log("Q");
        }
        if (Input.GetKeyDown(KeyCode.T))
        {
            SetHealth(20);
            Debug.Log("T");
        }

        if (Input.GetKeyDown(KeyCode.P))
        {
            PoisonDamage(2f,10);
            Debug.Log("P");
        }
    }


    // Take X amount of Damage 
    void TakeDamage(int damage)
    {
        if (stats.Armor.GetValue() <= damage) { 
            damage -= stats.Armor.GetValue();
            damage = Mathf.Clamp(damage, 0, int.MaxValue);

            slider.value -= damage;
        }
        if (slider.value <= 0)
        {
            Dead();
        }
    }

    // Death Status
    void Dead()
    {
        Debug.Log("You Are Dead");
        //filler for death scene
    }

    // Heal X amount of Damage
    void HealDamage(int damage)
    {
        if (slider.value < slider.maxValue)
        {
            slider.value += damage;
        }
    }

    // Set Max Health Permanently
    public void SetMaxHealth(int health)
    {
        slider.maxValue = health;
    }

    // Set Current Health
    public void SetHealth(int health)
    {
        slider.value = health;
    }

    // Increase MaxHealthPermanently
    public void IncreaseMaxHealth(int health)
    {
        slider.maxValue = slider.maxValue + health;
    }

    // Temporarily increase Max Health. waitTime = 5f ~ 5 seconds
    public void TempMaxHealth(float waitTime,int health)
    {
        StartCoroutine(TempHealthTime(waitTime, health)); // start time function
    }

    IEnumerator TempHealthTime(float waitTime, int health) 
    {
        slider.maxValue += health; // adds boost
        yield return new WaitForSeconds(waitTime);
        Debug.Log("Coroutine ended: " + Time.time + " seconds");
        slider.maxValue -= health; // remove boost
    }

    public void PoisonDamage(float waitTime,int health)
    {
        StartCoroutine(PoisonDuration(waitTime, health));
    }

    IEnumerator PoisonDuration(float waitTime,int health)
    {
        
        slider.value -= health;
        if (slider.value <= 0)
        {
            slider.value = 1;
        }

        yield return new WaitForSeconds(waitTime);

        if (slider.value > 1)
        {
            PoisonDamage(waitTime, health);
        }
          else Debug.Log("Coroutine ended: " + Time.time + " seconds" + slider.value);
        
       
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115

1 Answers1

0

This is because either stats or stats.Armor returns null. If that's excepted, you can do this

// Take X amount of Damage 
void TakeDamage(int damage)
{
    // note here the use of `?`, this basically says that if is null, use null and don't check after the dot.
    var armorValue = stats?.Armor?.GetValue();
    
    if (armorValue is null)
        return null;

    if (armorValue <= damage) { 
        damage -= armorValue;
        damage = Mathf.Clamp(damage, 0, int.MaxValue);

        slider.value -= damage;
    }
    if (slider.value <= 0)
    {
        Dead();
    }
}
Hervé
  • 760
  • 4
  • 9
  • [You shouldn't use `?.` operator on anything derived from `UnityEngine.Object`](https://stackoverflow.com/a/62678296/7111561) – derHugo Oct 20 '22 at 07:27