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;
}
}
}
}