using System; namespace UnityEngine.XR.Hands { /// /// A component that controls the visual representation for an in the scene. /// This component subscribes to events from an component to enable and disable a mesh renderer when tracking is acquired or lost. /// [HelpURL(XRHelpURLConstants.k_XRHandMeshController)] public class XRHandMeshController : MonoBehaviour { [SerializeField] [Tooltip("The XR Hand Tracking Events component that will be used to subscribe to hand tracking events.")] XRHandTrackingEvents m_XRHandTrackingEvents; [SerializeField] [Tooltip("The renderer that is rendering the hand mesh.")] Renderer m_HandMeshRenderer; [SerializeField] [Tooltip("If enabled, the hand mesh renderer will be enabled when the hand tracking is acquired.")] bool m_ShowMeshWhenTrackingIsAcquired = true; [SerializeField] [Tooltip("If enabled, the hand mesh renderer will be disabled when the hand tracking is lost.")] bool m_HideMeshWhenTrackingIsLost = true; bool m_HandIsTracked; /// /// Whether the hand for this visual is currently being tracked /// public bool handIsTracked => m_HandIsTracked; /// /// If enabled, the hand mesh renderer will be enabled when the hand tracking is acquired. /// public bool showMeshWhenTrackingIsAcquired { get => m_ShowMeshWhenTrackingIsAcquired; set { m_ShowMeshWhenTrackingIsAcquired = value; if (Application.isPlaying) UpdateRendererVisibility(); } } /// /// If enabled, the hand mesh renderer will be disabled when the hand tracking is lost. /// public bool hideMeshWhenTrackingIsLost { get => m_HideMeshWhenTrackingIsLost; set { m_HideMeshWhenTrackingIsLost = value; if (Application.isPlaying) UpdateRendererVisibility(); } } /// /// The renderer used to draw the hand mesh. /// public Renderer handMeshRenderer { get => m_HandMeshRenderer; set { m_HandMeshRenderer = value; if (Application.isPlaying) UpdateRendererVisibility(); } } /// /// The component that will be the source of hand tracking events for this mesh controller. /// public XRHandTrackingEvents handTrackingEvents { get => m_XRHandTrackingEvents; set { if (Application.isPlaying) UnsubscribeFromHandTrackingEvents(); m_XRHandTrackingEvents = value; if (Application.isPlaying && isActiveAndEnabled) SubscribeToHandTrackingEvents(); } } /// /// See . /// protected virtual void Reset() { TryGetComponent(out m_XRHandTrackingEvents); } /// /// See . /// protected virtual void OnEnable() { if (m_XRHandTrackingEvents == null) TryGetComponent(out m_XRHandTrackingEvents); if (m_XRHandTrackingEvents == null) { Debug.LogError("The XR Hand Mesh Controller requires an XR Hand Tracking Events component to subscribe to hand tracking events.", this); return; } SubscribeToHandTrackingEvents(); } /// /// See . /// protected virtual void OnDisable() { UnsubscribeFromHandTrackingEvents(); } void SubscribeToHandTrackingEvents() { if (m_XRHandTrackingEvents != null) { m_XRHandTrackingEvents.bindableHandIsTracked.SubscribeAndUpdate(OnTrackingChanged); } } void UnsubscribeFromHandTrackingEvents() { if (m_XRHandTrackingEvents != null) { m_XRHandTrackingEvents.bindableHandIsTracked.Unsubscribe(OnTrackingChanged); } } void OnTrackingChanged(bool isTracked) { m_HandIsTracked = isTracked; UpdateRendererVisibility(); } void UpdateRendererVisibility() { if (m_HandIsTracked && m_ShowMeshWhenTrackingIsAcquired) { m_HandMeshRenderer.enabled = true; } else if (!m_HandIsTracked && m_HideMeshWhenTrackingIsLost) { m_HandMeshRenderer.enabled = false; } } } }