How to add animations to prefabs in Unity VR

Mapping input to animations

We can add animations to prefabs in Unity and make them act as we want by using an Animation Controller and creating animations. However, if we want to trigger those animations when a certain button is pressed, we need to make use of the UnityEngine.XR library. Specifically, we use its InputDevice class to read input from the user device and then trigger the animation.

Pre-setup scene

To have our input from the hand-held device trigger the animation attached to a prefab, the prefab needs to have an Animator component attached to it, and an Animation Controller that has the animations set up. This is explained thoroughly in the Answer linked above. In our case, the prefabs are the hand models that we place on the controller.

Creating the C# script

To create the script, we can right-click inside the project window and select "Create > C# Script."

We need to create a C# script that performs the following tasks:

  • Determining the input device that we read the input from

  • Animating the prefab

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
public enum HandType
{
Left,
Right
}
public class XRHandController : MonoBehaviour
{
public HandType handType;
private Animator animator;
private InputDevice inputDevice;
private float ok;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
inputDevice = GetInputDevice();
}
// Update is called once per frame
void Update()
{
inputDevice.TryGetFeatureValue(CommonUsages.grip, out ok);
animator.SetFloat("ok", ok);
}
InputDevice GetInputDevice()
{
InputDeviceCharacteristics controllerChar = InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Controller;
if (handType == HandType.Left)
{
controllerChar= controllerChar | InputDeviceCharacteristics.Left;
}
else
{
controllerChar = controllerChar | InputDeviceCharacteristics.Right;
}
List<InputDevice> inputDevices = new List<InputDevice>();
InputDevices.GetDevicesWithCharacteristics(controllerChar, inputDevices);
return inputDevices[0];
}
}

Explanation

  • Lines 6–10: Here, we create a public enum to determine which hand the script is attached to.

  • Lines 12–51: This part contains the class, which contains the methods included in the script.

    • Line 14: This line contains the handType variable of type enum HandType. It determines which hand the script is attached to.

    • Line 15: This line contains the animator, which is used later in Line 22 to get the animator component attached to the GameObject.

    • Line 16: This is the inputDevice variable that we use again in Line 23 to acquire the hand-held input device. It is of the type InputDevice, which is a class of UnityEngine.XR and contains the information about the input devices in the XR system.

    • Line 17: This line contains the variable ok of type float, which we use to add effect to our animation.

Note: To read more on InputDevice, please follow this link.

  • Line 33: This line contains the GetInputDevice() method that we use to determine and acquire the hand-held device being used.

    • Line 35: Here, we declare a variable controllerChar of type InputDeviceCharacteristics, which is a bitmask of flags that determines which properties a device has or does not have. We first check if it is a HeldInHand device or a Controller, and it sets the first bit.

    • Line 37–44: This part contains the code block responsible for determining which side of the enum HandType we declared earlier the InputDevice is based on, and sets the respective bit.

    • Line 46: Here, we declare a list of type InputDevice because in the next line, the method we use takes it as a parameter.

    • Line 47: This line uses the GetDeviceWithCharacteristics method and takes as a parameter the device characteristics in the form of a bitmask (in our case, controllerChar) and the list in which it returns the devices found with the passed characteristics.

    • Line 49: Finally, we return the first index of the list, as it only finds one device associated with the characteristics that we passed it.

  • Lines 27–31: These lines contain the built-in Update() method, which performs the following two tasks:

    • Line 29: Here, we use the inputDevice we acquired using the GetInputDevice() method. We check if its "grip" button is being pressed and outputs the value in ok variable.

    • Line 30: Finally we use the attached Animator component and set the float value associated with its blend tree to trigger the animation.

Output

When we build and run the unity project, we see that the animation on the hand prefab is triggered when we press the grip button on the controller.

Copyright ©2024 Educative, Inc. All rights reserved