docs.unity3d.com
    Show / Hide Table of Contents

    Process joints

    If you wish to process or filter joint data before it's returned to the subsystem caller, derive a class from IXRHandProcessor and register it with XRHandSubsystem.RegisterProcessor in a static method decorated with [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]. IXRHandProcessors with a lower callbackOrder value will be called sooner than this with higher values for their callbackOrder.

    If you wish to access the joint data before anyone has had a chance to process the joints, you can use XRHandSubsystem.preprocessJoints.

    Note

    This is an advanced use case. Typically, you should use the XRHandSubsystem's updatedHands callback and just consume the data instead of altering it in any way.

    Use extension methods in UnityEngine.XR.Hands.Processing.XRHandProcessingUtility. The below sample code demonstrates how to set pose data before it's returned to the subsystem.

    using UnityEngine.XR.Hands.Processing;
    
    public class MyHandProcessor : MonoBehaviour, IXRHandProcessor
    {
        public int callbackOrder => 0;
    
        public void ProcessJoints(XRHandSubsystem subsystem, XRHandSubsystem.UpdateSuccessFlags successFlags, XRHandSubsystem.UpdateType updateType)
        {
            var leftHand = subsystem.leftHand;
            leftHand.SetRootPose(Pose.identity);
            subsystem.SetCorrespondingHand(leftHand);
    
            var rightHand = subsystem.rightHand;
            rightHand.SetRootPose(Pose.identity);
            subsystem.SetCorrespondingHand(rightHand);
    
            var leftJoints = leftHand.GetRawJointArray();
            var rightJoints = rightHand.GetRawJointArray();
            for (int jointIndex = 0; jointIndex < leftJoints.Length; ++jointIndex)
            {
                var leftJoint = leftJoints[jointIndex];
                leftJoint.SetPose(Pose.identity);
                leftJoints[jointIndex] = leftJoint;
    
                var rightJoint = rightJoints[jointIndex];
                rightJoint.SetPose(Pose.identity);
                rightJoints[jointIndex] = rightJoint;
            }
        }
    
        void Update()
        {
            if (m_Registered)
                return;
    
            SubsystemManager.GetSubsystems(s_SubsystemsReuse);
            if (s_SubsystemsReuse.Count == 0)
                return;
    
            m_Subsystem = s_SubsystemsReuse[0];
            m_Subsystem.RegisterProcessor(this);
            m_Registered = true;
        }
    
        void OnDisable()
        {
            if (m_Subsystem != null)
            {
                m_Subsystem.UnregisterProcessor(this);
                m_Subsystem = null;
                m_Registered = false;
            }
        }
    
        bool m_Registered;
        XRHandSubsystem m_Subsystem;
    
        static List<XRHandSubsystem> s_SubsystemsReuse = new List<XRHandSubsystem>();
    }
    

    See sample HandProcessor script in the HandVisualizer sample for a more useful example of how to use this functionality.

    Back to top
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023