Unity 2D Error NullReferenceException

Hello, I was following a tutorial on how to make a game in Unity and I thought i was doing everything right, but when I try to throw the knife the player does the animation, the knife spawns, but just sits there.

here is the error:
NullReferenceException: Object reference not set to an instance of an object
Character.ThrowKnife (Int32 value) (at Assets/Scripts/Character.cs:43)
Player.ThrowKnife (Int32 value) (at Assets/Scripts/Player.cs:171)

here is the code for the Character error:

using UnityEngine;
using System.Collections;

public abstract class Character : MonoBehaviour {

    protected Animator myAnimator;

    [SerializeField]
    private Transform KnifePos;

    [SerializeField]
    protected float movementSpeed;

    protected bool facingRight;

    [SerializeField]
    protected GameObject knifePrefab;

    public bool Attack { get; set; }

    // Use this for initialization
    public virtual void Start () {
        facingRight = true;
        myAnimator = GetComponent<Animator>();
    }
   
    // Update is called once per frame
    void Update () {
   
    }

    public void ChangeDirection()
    {
        facingRight = !facingRight;
        transform.localScale = new Vector3(transform.localScale.x * -1, 1, 1);
    }

    public virtual void ThrowKnife(int value)
    {
        if (facingRight)
        {
            GameObject tmp = (GameObject)Instantiate(knifePrefab, KnifePos.position, Quaternion.Euler(new Vector3(0, 0, -90)));
            tmp.GetComponent<Knife>().Initialize(Vector2.right);
        }
        else
        {
            GameObject tmp = (GameObject)Instantiate(knifePrefab, KnifePos.position, Quaternion.Euler(new Vector3(0, 0, 90)));
            tmp.GetComponent<Knife>().Initialize(Vector2.left);
        }
    }

}

and here is the code for the Player error:

using UnityEngine;
using System.Collections;

public class Player : Character
{

    private static Player instance;

    public static Player Instance
    {
        get
        {
            if (instance == null)
            {
                instance = GameObject.FindObjectOfType<Player>();
            }
            return instance;
        }

        set
        {
            instance = value;
        }
    }

    [SerializeField]
    private Transform[] groundPoints;

    [SerializeField]
    private float groundRadius;

    [SerializeField]
    private LayerMask whatIsGround;

    [SerializeField]
    private bool airControl;

    [SerializeField]
    private float jumpForce;

    public Rigidbody2D MyRigidbody { get; set; }

    public bool Slide { get; set; }
    public bool Jump { get; set; }
    public bool OnGround { get; set; }

    // Use this for initialization

    public override void Start()
    {

        base.Start();

        MyRigidbody = GetComponent<Rigidbody2D>();

    }

    void Update()
    {
        handleInput();
    }

    // Update is called once per frame
    void FixedUpdate()
    {

        float horizontal = Input.GetAxis("Horizontal");

        OnGround = IsGrounded();

        HandleMovement(horizontal);

        Flip(horizontal);

        HandleLayers();

    }

    private void HandleMovement(float horizontal)
    {
        if (MyRigidbody.velocity.y < 0)
        {
            myAnimator.SetBool("land", true);
        }
        if (!Attack && !Slide && (OnGround || airControl))
        {
            MyRigidbody.velocity = new Vector2(horizontal * movementSpeed, MyRigidbody.velocity.y);
        }
        if (Jump && MyRigidbody.velocity.y == 0)
        {
            MyRigidbody.AddForce(new Vector2(0, jumpForce));
        }

        myAnimator.SetFloat("speed", Mathf.Abs(horizontal));

    }

    private void handleInput()
    {

        if (Input.GetKeyDown(KeyCode.Space))
        {
            myAnimator.SetTrigger("jump");
        }

        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            myAnimator.SetTrigger("attack");
        }

        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            myAnimator.SetTrigger("slide");
        }

        if (Input.GetKeyDown(KeyCode.Mouse1))
        {
            myAnimator.SetTrigger("throw");
        }

    }

    private void Flip(float horizontal)
    {
        if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
        {
            ChangeDirection();
        }
    }

    private bool IsGrounded()
    {
        if (MyRigidbody.velocity.y <= 0)
        {
            foreach (Transform point in groundPoints)
            {
                Collider2D[] colliders = Physics2D.OverlapCircleAll(point.position, groundRadius, whatIsGround);

                for (int i = 0; i < colliders.Length; i++)
                {
                    if (colliders[i].gameObject != gameObject)
                    {
                        return true;
                    }
                }

            }
        }

        return false;

    }

    private void HandleLayers()
    {
        if (!OnGround)
        {
            myAnimator.SetLayerWeight(1, 1);
        }
        else
        {
            myAnimator.SetLayerWeight(1, 0);
        }
    }

    public override void ThrowKnife(int value)
    {

        if (!OnGround && value == 1 || OnGround && value == 0)
        {
            base.ThrowKnife(value);
        }
    }

}

Thanks for posting the full code.

So your player class calls “base.ThrowKnife(value)”.

The base class is Character, which errors at this line:

tmp.GetComponent<Knife>().Initialize(Vector2.right);

So something in that line is null.

It’s probably that “GetComponent()” is returning null, meaning your “knifePrefab” is missing the Knife component, or perhaps you left the knifePrefab variable empty in the inspector and “tmp” has no value.

Thanks for your help @LiterallyJeff ! The knifePrefab didn’t have the script component, so i just added it, and it worked!

1 Like