Need help with OnUse() script!

So I have a raycast script that on pressing E it activates the OnUse() script on hit game object if it has correct tag. Now I have a desk with shelf and I want the desk to open when pressed E upon, but because its a prefab I needed to use instantiate.
Im having a problem that if I want the animation to play it cant cause it always creates a new clone and somehow doesnt get the parent’s animator.

So the problem is I dont know how to get the animator to play and im getting this error code: NullReferenceException: Object reference not set to an instance of an object

So here is my shelf script:

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

public class WoodenDesk : MonoBehaviour {

    public GameObject animObject;
    Animator anim;

    // Use this for initialization
    void Start () {
        anim = animObject.GetComponent<Animator>();
    }
	
	// Update is called once per frame
	void Update () {
		
	}

    void OnUse()
    {
        Debug.Log("IT WORKSSS");
        anim.SetTrigger("OpenShelf");
    }
}

And here is parts of my raycast code:

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

public class CameraRaycast1 : MonoBehaviour {

    [SerializeField] float interactionRayLength;
    [SerializeField] KeyCode interactionKey;
    public Text textObject;
    GameObject _spawnedObj;

void Update () {
        RaycastCheck();
	}

        if (hitFound && interactionRayHit.transform.tag == "interactable" || hitFound && interactionRayHit.transform.tag =="iprefab" )
        {
            GameObject hitGameobject = interactionRayHit.transform.gameObject;
            
            string hitFeedback = hitGameobject.name;
            textObject.enabled = true;
            textObject.text = string.Format("Press {0} to interact with {1}.", interactionKey, hitFeedback);
            //Debug.Log(hitFeedback);
            if (Input.GetKeyDown(interactionKey))
            {
                _spawnedObj = Instantiate(hitGameobject) as GameObject;
                _spawnedObj.SendMessage("OnUse", SendMessageOptions.RequireReceiver);
            }
        }

im quite new so if you need info please ask,

You instantiate an object (_spawnedObj) and run its OnUse method before that objects Start method has a chance to fire, which means that its anim field is still null. You might want to add a null check to your OnUse method:


void OnUse()
{
  if (anim == null) anim = GetComponent<Animator>();
  Debug.Log("IT WORKSSS");
  anim.SetTrigger("OpenShelf");
}

EDIT

Or, if you don’t like it checking that on every use , you can move the Animator caching to a separate method and running that method after creating an instance:

// Use this for initialization
void Start () {
    Initialize();
}

public void Initialize() {
    anim = animObject.GetComponent<Animator>();
}

...

    _spawnedObj = Instantiate(hitGameobject) as GameObject;
    _spawnedObj.SendMessage("Initialize", SendMessageOptions.RequireReceiver);
    _spawnedObj.SendMessage("OnUse", SendMessageOptions.RequireReceiver);