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.
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.
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 updatevoid Start(){animator = GetComponent<Animator>();inputDevice = GetInputDevice();}// Update is called once per framevoid 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];}}
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.
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.