- 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. :)