Stratasys-450mc-VR/Assets/XRI_Examples/SocketInteractors/Scripts/XRInfiniteInteractable.cs

96 lines
3.0 KiB
C#

using UnityEngine.XR.Interaction.Toolkit;
namespace UnityEngine.XR.Content.Interaction
{
/// <summary>
/// This component makes sure that the attached <c>Interactor</c> always have an interactable selected.
/// This is accomplished by forcing the <c>Interactor</c> to select a new <c>Interactable Prefab</c> instance whenever
/// it loses the current selected interactable.
/// </summary>
[DisallowMultipleComponent]
[RequireComponent(typeof(XRBaseInteractor))]
public class XRInfiniteInteractable : MonoBehaviour
{
[SerializeField]
[Tooltip("Whether infinite spawning is active.")]
bool m_Active = true;
[SerializeField]
[Tooltip("If true then during Awake the Interactor \"Starting Selected Interactable\" will be overriden by an " +
"instance of the \"Interactable Prefab\".")]
bool m_OverrideStartingSelectedInteractable;
[SerializeField]
[Tooltip("The Prefab or GameObject to be instantiated and selected.")]
XRBaseInteractable m_InteractablePrefab;
XRBaseInteractor m_Interactor;
/// <summary>
/// Whether infinite spawning is enabled.
/// </summary>
public bool active
{
get => m_Active;
set
{
m_Active = value;
if (enabled && value && !m_Interactor.hasSelection)
InstantiateAndSelectInteractable();
}
}
void Awake()
{
m_Interactor = GetComponent<XRBaseInteractor>();
if (m_OverrideStartingSelectedInteractable)
OverrideStartingSelectedInteractable();
}
void OnEnable()
{
if (m_InteractablePrefab == null)
{
Debug.LogWarning("No interactable prefab set - nothing to spawn!");
enabled = false;
return;
}
m_Interactor.selectExited.AddListener(OnSelectExited);
}
void OnDisable()
{
m_Interactor.selectExited.RemoveListener(OnSelectExited);
}
void OnSelectExited(SelectExitEventArgs selectExitEventArgs)
{
if (selectExitEventArgs.isCanceled || !active)
return;
InstantiateAndSelectInteractable();
}
XRBaseInteractable InstantiateInteractable()
{
var socketTransform = m_Interactor.transform;
return Instantiate(m_InteractablePrefab, socketTransform.position, socketTransform.rotation);
}
void OverrideStartingSelectedInteractable()
{
m_Interactor.startingSelectedInteractable = InstantiateInteractable();
}
void InstantiateAndSelectInteractable()
{
if (!gameObject.activeInHierarchy || m_Interactor.interactionManager == null)
return;
m_Interactor.interactionManager.SelectEnter((IXRSelectInteractor)m_Interactor, InstantiateInteractable());
}
}
}