New input system Null Reference Exception error

Hello All,

I’m using the New Input handler and when my scene changes i’m getting the below error

NullReferenceException: Object reference not set to an instance of an object
PlayerInputHandler.OnDisable () (at Assets/Scripts/PlayerInputHandler.cs:73)
UnityEngine.Object:Destroy(Object)
PlayerInputHandler:Awake() (at Assets/Scripts/PlayerInputHandler.cs:40)

I’ve pinned it down to when i destroy the Handlers clone when a new level is loaded. So i remove the destroy command and the error disspaears. However, i then get a clone as i have the handler as do not destroy.

using System.Collections;
using System.Collections.Generic;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerInputHandler : MonoBehaviour
{
    [Header("Input Action Asset")]
    [SerializeField] private InputActionAsset playerControls;

    [Header("Action Map Name Reference")]
    [SerializeField] private string actionMapName = "Player";

    [Header("Action Name Reference")]
    [SerializeField] private string move = "Move";
    [SerializeField] private string attack = "Attack";

    private InputAction moveAction;
    private InputAction attackAction;

    public Vector2 MoveInput { get; private set; }
    public bool AttackTriggered { get; private set; }
    private static PlayerInputHandler instance;
    public static PlayerInputHandler Instance
    {
        get
        {
            if (instance == null) instance = GameObject.FindObjectOfType<PlayerInputHandler>();
            return instance;

        }

    }

    private void Awake()
    {
        if(Player.Instance.level > 1)
        {
            if (GameObject.Find("PlayerInputHandler")) Destroy(gameObject);
        }
        
        moveAction = playerControls.FindActionMap(actionMapName).FindAction(move);
        attackAction = playerControls.FindActionMap(actionMapName).FindAction(attack);

        RegisterInputActions();
    }

    void Start()
    {
        DontDestroyOnLoad(gameObject);
    }

    void RegisterInputActions()
    {
        moveAction.performed += context => MoveInput = context.ReadValue<Vector2>();
        moveAction.canceled += context => MoveInput = Vector2.zero;

        attackAction.performed += context => AttackTriggered = true;
        attackAction.canceled += context => AttackTriggered = false;
    }

    private void OnEnable()
    {
        moveAction.Enable();
        attackAction.Enable();

        InputSystem.onDeviceChange += OnDeviceChange;
    }

    private void OnDisable()
    {
        moveAction.Disable();
        attackAction.Disable();

        InputSystem.onDeviceChange -= OnDeviceChange;
    }

    private void OnDeviceChange(InputDevice device, InputDeviceChange change)
    {
        switch (change) 
        {
            case InputDeviceChange.Disconnected:
                Debug.Log("Device Disconnected: " + device.name);
                break;
            case InputDeviceChange.Reconnected:
                Debug.Log("Device Reconnected: " + device.name);
                break;
        }
    }
}

So my question is do i remove the do not destroy and let each scene generate the handler or is there a better way to write this script?

Thanks in advance.

Generate the handler once and use DontDestroyOnLoad() instead of repeatedly destroying and recreating it. You just check if it’s already in the scene and, if so, don’t make a new one.