OnStateEnter and OnStateUpdate NullReferenceException

Hello, I am making a 2D pixel Art game, and I am using state machine behaviors to make an enemy chase the player. However, whenever the enemy gets within chase range, the first line in both OnStateEnter AND OnStateUpdate hits the console with a NullReferenceException. Does anyone else get this error? Is it a bug? How do I fix it?

(Errors on line 29 and 45 of Chase Script)

Chase Script:

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

public class BasicZombieChaseBehaviour : StateMachineBehaviour
{

    private Transform player;
    public float distanceFromPlayer;
    public float speed;
    public Vector2 movement;
    Transform pos;

    public float attackCooldown;
    public float startAttackCooldown;
    public float damageToPlayer;
    public Transform[] attackPos;
    public float attackRange;
    public int attackSide;
    public LayerMask enemyLayers;
    public PlayerStats playerStats;

    public BasicZombie basicZombie;

    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {

        basicZombie = animator.transform.parent.GetComponent<BasicZombie>();
        attackPos = basicZombie.attackPositions;

        startAttackCooldown = 0.35f;

        pos = animator.transform;
        speed = 2.25f;
        player = GameObject.FindGameObjectWithTag("Player").transform;
        playerStats = player.GetComponent<PlayerStats>();

    }

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {

        movement.x = pos.position.x - player.position.x;
        movement.y = pos.position.y - player.position.y;
        animator.SetFloat("Horizontal", -movement.x);
        animator.SetFloat("Vertical", -movement.y);
        distanceFromPlayer = Vector2.Distance(player.position, animator.transform.position);
        animator.SetFloat("playerDist", distanceFromPlayer);
        animator.transform.position = Vector2.MoveTowards(animator.transform.position, player.position, speed * Time.deltaTime);

        if (distanceFromPlayer <= 0.65)
        {

            if(attackCooldown  <= 0)
            {

                hitTarget(animator);

            } else
            {

                attackCooldown -= Time.deltaTime;

            }

        }

        if (distanceFromPlayer > 7)
        {

            animator.SetBool("isChasing", false);

        }

    }

    public void hitTarget(Animator animator)
    {

        attackCooldown = startAttackCooldown;
        sideFacing(animator);
        attackSide = animator.GetInteger("SideFacing");

        Collider2D[] enemiesToHit = Physics2D.OverlapCircleAll(attackPos[attackSide].position, attackRange, enemyLayers);

        for (int i = 0; i < enemiesToHit.Length; i++)
        {

            damageToPlayer = playerStats.damagePerHit;
            enemiesToHit.GetComponent<PlayerStats>().takeDamage(damageToPlayer);

        }

    }

    public void sideFacing(Animator animator)
    {

        if (animator.GetFloat("Vertical") == -1 || animator.GetFloat("Vertical") == -1 && animator.GetFloat("Horizontal") == 1 || animator.GetFloat("Vertical") == -1 && animator.GetFloat("Horizontal") == -1)
        {

            animator.SetInteger("SideFacing", 2);

        }
        else if (animator.GetFloat("Vertical") == 1 || animator.GetFloat("Vertical") == 1 && animator.GetFloat("Horizontal") == 1 || animator.GetFloat("Vertical") == 1 && animator.GetFloat("Horizontal") == -1)
        {

            animator.SetInteger("SideFacing", 0);

        }
        else if (animator.GetFloat("Horizontal") == 1)
        {

            animator.SetInteger("SideFacing", 1);

        }
        else if (animator.GetFloat("Horizontal") == -1)
        {

            animator.SetInteger("SideFacing", 3);

        }

    }

}

Aaand my Basic Zombie Script:

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

public class BasicZombie : MonoBehaviour
{

    public float health;

    public Transform[] attackPositions;

    private void Update()
    {
    
        if(health <= 0)
        {

            die();

        }

    }

    public void die()
    {

        Debug.Log("Enemy Killed");
        Destroy(gameObject);

    }

    public void takeDamage(float damage)
    {

        health -= damage;

    }

}

Player Stats Script:
```csharp
*using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerStats : MonoBehaviour
{

public Animator animator;
public bool hasKnife;
public bool hasFists;

public float health;
public float maxHealth;

public float hunger;
public float maxHunger;
float hungerDecreaseRate = 1.5f;

public float thirst;
public float maxThirst;
float thirstDecreaseRate = 2f;

public bool isDead;

public float hasNoHungerHealthDecrease;
public float hasNoThirstHealthDecrease;

public bool itemEquipped;

public float damagePerHit;

public void Start()
{

    hasFists = true;

    isDead = false;
    health = maxHealth;
    hunger = maxHunger;
    thirst = maxThirst;

    itemEquipped = false;

}

public void FixedUpdate()
{

    if (hasKnife)
    {

        damagePerHit = 15;

    } else if (hasFists) {

        damagePerHit = 5;

    }

    if (!isDead && hunger > 0)
    {

        hunger = hunger - hungerDecreaseRate * Time.fixedDeltaTime;

    }

    if(!isDead && thirst > 0)
    {

        thirst = thirst - thirstDecreaseRate * Time.fixedDeltaTime;

    }

    if (thirst <= 0 && !isDead)
    {

        health = health - hasNoThirstHealthDecrease * Time.fixedDeltaTime;

    }
    if (hunger <= 0 && !isDead)
    {

        health = health - hasNoHungerHealthDecrease * Time.fixedDeltaTime;

    }

    if (health <= 0)
    {

        isDead = true;

    }

}

public void equipItem(string item)
{

    //Debug.Log(item);

    if(item == "knife")
    {

        hasKnife = !hasKnife;
        if(!hasKnife)
        {

            hasFists = true;

        } else {

            hasFists = false;

        }
        animator.SetBool("HasKnife", hasKnife);

    }

}

public void takeDamage(float damage)
{

    health -= damage;

}

}*
```
Help would be greatly appreciated! Thank you!

Please use code-tags when posting code. You must be able to see that the above is a huge wall of text that is very hard to follow.

Whatever the reason you get this exception, the cause is always the same and it’s the most posted problem because it’s a basic C# problem, not a Unity problem and not related to state-machines or anything else.

You’ve simply got a field or property you’ve not initialized so is NULL. The error tells you exactly which line/column this is but we don’t know that because you didn’t post the full error and couldn’t figure out the line because it’s all plain text. Go to that line and see what’s actually NULL, it’s easy to do. Then figure out why it’s not been initialized.

I see an awful lot of GetComponents which you are assuming are there but if they’re not then they return NULL and then you proceed to use them even if that are NULL. The line/column number reported will tell you though where it is.

But I’ve defined the variables above the start method, I just don’t understand why it can’t find it, when it has been defined above it. Sorry if it is an obvious answer of something, but I am relatively new.

(Also about the code yes, I realized I forgot to do that, fixed now)

Did you read what I wrote though? I told you that the error actually tells you which line/column and therefore what is actually NULL.

You want an answer but I’ve given you it above.

Okay so now you’ve edited it you say line 29 which is “basicZombie = animator.transform.parent.GetComponent();” but the column will tell you which thing. It might be that the transform doesn’t have a parent so it’s NULL but you ask for the component on NULL regardless. To clarify, if there is no parent you’re doing “NULL.GetComponent()”. :slight_smile:

As for the other, pos or player are likely not initialized. It’s okay thinking they are but you need to debug it or use “Debug.Log(xxx)” to check it to be sure.

Ahhhh. Ok Thanks. I was realizing that when I rearranged the code. Thank you!

1 Like

This should save you a lot of time in the future with NullRefs. Why?

Because the answer is always the same… ALWAYS. It is the single most common error ever.

Don’t waste your life spinning around and round on this error. Instead, learn how to fix it fast… it’s EASY!!

Some notes on how to fix a NullReferenceException error in Unity3D

  • also known as: Unassigned Reference Exception
  • also known as: Missing Reference Exception
  • also known as: Object reference not set to an instance of an object

http://plbm.com/?p=221

The basic steps outlined above are:

  • Identify what is null
  • Identify why it is null
  • Fix that.

Expect to see this error a LOT. It’s easily the most common thing to do when working. Learn how to fix it rapidly. It’s easy. See the above link for more tips.

You need to figure out HOW that variable is supposed to get its initial value. There are many ways in Unity. In order of likelihood, it might be ONE of the following:

  • drag it in using the inspector
  • code inside this script initializes it
  • some OTHER external code initializes it
  • ? something else?

This is the kind of mindset and thinking process you need to bring to this problem:

https://discussions.unity.com/t/814091/4

Step by step, break it down, find the problem.

Here is a clean analogy of the actual underlying problem of a null reference exception:

https://discussions.unity.com/t/840647/7

Thanks! I am getting better every day :slight_smile:

1 Like