96 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			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());
 | |
|         }
 | |
|     }
 | |
| }
 |