- Home /
 
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,
Answer by LCStark · Sep 18, 2018 at 07:12 PM
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);
 
              But doesnt it check it on every use still? As you press E it does the initialize again?
Right, because you instantiate it on use. $$anonymous$$y mistake, I was looking at another piece of code at the same time and got confused between the two. :)
Your answer