Triggering animation on interaction of another GameObject

Hello, I am trying to figure out how to make a button (E to interact with) trigger an animation on another GameObject. Any way to do this?

1 Like

Hello there!

One way that this could be done is by first having the other GameObject have a collider that is set to be isTrigger, then using a script that is on that GameObject, you use a void OnTriggerEnter that detects if the player is within that collider, and if so, depending on which Input System you’re using, you do something along the lines of:

if(ButtonPressed == E)
{
     TriggerAnimation();
}

I am also linking the documentation for how to trigger an animation within script here: Unity - Scripting API: Animation.Play

Finally an answer! I’ll try it right now!

Tried playing around with yours and the logs scripts and got this

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

public class Interact_Garage : MonoBehaviour
{
    private Animation anim;
    void Update()
    {
        OnTriggerEnter();
    }

    void OnTriggerEnter()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            Debug.Log("Opening");
            anim.Play("Open_Garage");
        }


    }

        
         
}

However, I keep getting this error

NullReferenceException: Object reference not set to an instance of an object
Interact_Garage.OnTriggerEnter () (at Assets/Scripts/Interact_Garage.cs:19)
Interact_Garage.Update () (at Assets/Scripts/Interact_Garage.cs:11)

Interact_Garage Being the name of the c# file

Ah okay I see the issue with it, the OnTriggerEnter(); shouldn’t be in the update, in fact there should be no Update method due to OnTriggerEnter working on its own, so try just

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

public class Interact_Garage : MonoBehaviour
{
    private Animation anim;

    void OnTriggerEnter()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            Debug.Log("Opening");
            anim.Play("Open_Garage");
        }


    }

        
}

if it doesn’t work, then dw, I would like to see the next error that pops up after making that change.

Now it doesn’t work at all.

Alrighty gimme a bit, i’ll make my own project in a Unity version that isn’t Unity 6 to test things out

1 Like

Alright I got it to work on my end, lemme just write down the explanation for it so that you could understand for future use.

Basically the first error occurred due to the Animation component “anim” not having any component from the your garage game object assigned to it. Typically this is done by using either a Start() or an Awake() function, where you then use

private void Awake()
{
    anim = GetComponent<Animation>();
}

Note: This is to get a component that exists within the same game object the script is currently in.

Now in order for what you want to work, it needs to instead use the Animator component, as that is what the .Play() method uses, which would be as follows:

private void Awake()
{
    anim = GetComponent<Animator>();
}

Once that is done, I was wrong at first about not using any Update() function, but after testing it myself, instead what the Update() function requires is the use of the input as well as a way to detect if the player is currently inside of the trigger collider, where you would use the following code:

private void Update()
{
    if (Input.GetKeyDown(KeyCode.E) && insideTrigger)
    {
        Debug.Log("Button Pressed");

        anim.Play("anim_Open");
    }
}

the insideTrigger is a Boolean that is marked true/false depending on the OntriggerEnter/Exit methods, which I will now detail as follows:

private void OnTriggerEnter(Collider other)
{
    if(other.tag == "Player")
    {
        insideTrigger = true;
    }
}

private void OnTriggerExit(Collider other)
{
    insideTrigger = false;
}

You would also need to make sure that your player game object has the Player tag (if there is none yet, you should create one and set it for your player specifically), that way the only way that the insideTrigger variable is made true is if the player is inside that trigger, and makes sure that once the player leaves the trigger, it is reverted back to false.

I will now provide you with the full code together.

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

public class Interact_Garage : MonoBehaviour
{
    bool insideTrigger = false;
    private Animator anim;

    private void Awake()
    {
        anim = GetComponent<Animator>();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.E) && insideTrigger)
        {
            Debug.Log("Button Pressed");

            anim.Play("anim_Open");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if(other.tag == "Player")
        {
            insideTrigger = true;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        insideTrigger = false;
    }
}

Hope this works!

Also make sure to change the anim variable into an Animator

private Animator anim;

This change is in the full code I provided as well

Let me share the files to the game, but it is asking for me to put an animator on the button.
https://drive.google.com/file/d/1YRWipMiT4ntVvpoukyfsKWKMvzK72vGT/view?usp=sharing

Okay I see, you want to have specific buttons be able to open a separate game object in a first person game, I didn’t know but fortunately that’s a simple fix with the trigger method we’re going for.

You have to do a few things for it to work.

First things first, you needed to change the anim.play(“animOpen”) to match your own animation names, which in this case you would change it to anim.play(“Open_Garage”);

Secondly, in order to get the animator of another game object, you would need to declare a public variable at the top of the script in order for you to be able to get the animator component of that game object, this would be public GameObject garageDoor;

Lastly, change the Awake code to also include that change so it would now be:

anim = garageDoor.GetComponent();

With all these changes made, here’s the resulting script.

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

public class Interact_Garage : MonoBehaviour
{
    bool insideTrigger = false;
    private Animator anim;
    public GameObject garageDoor;

    private void Awake()
    {
        anim = garageDoor.GetComponent<Animator>();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.E) && insideTrigger)
        {
            Debug.Log("Button Pressed");

            anim.Play("Open_Garage");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Player")
        {
            insideTrigger = true;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        insideTrigger = false;
    }
}

Now then, you will need to drag and drop the Garage Door game object onto the new Garage Door variable within the Editor, which is located on your button, which looks as follows

After that, I would suggest creating a new animation clip called DoorClosed that would keep the door closed until the button is pressed.
image

And also making that new clip the Layer Default State.


That way the Open_Garage animation doesn’t play until it the button is pressed.

Try making all these changes!

This works, Thank you so much!

1 Like