namespace VRTK.Prefabs.Interactions.Interactables { using UnityEngine; using UnityEngine.Events; using System; using System.Collections.Generic; using Malimbe.XmlDocumentationAttribute; using Malimbe.PropertySerializationAttribute; using Malimbe.MemberClearanceMethod; using Malimbe.MemberChangeMethod; using Zinnia.Rule; using Zinnia.Extension; using Zinnia.Data.Attribute; using Zinnia.Data.Collection.List; using Zinnia.Tracking.Collision; using VRTK.Prefabs.Interactions.Interactors; using VRTK.Prefabs.Interactions.Interactables.Touch; using VRTK.Prefabs.Interactions.Interactables.Grab; /// /// The public interface into the Interactable Prefab. /// public class InteractableFacade : MonoBehaviour { /// /// Defines the event with the . /// [Serializable] public class UnityEvent : UnityEvent { } #region Touch Events /// /// Emitted when the Interactable is touched for the first time by an Interactor. /// [Header("Touch Events"), DocumentedByXml] public UnityEvent FirstTouched = new UnityEvent(); /// /// Emitted when an Interactor touches the Interactable. /// [DocumentedByXml] public UnityEvent Touched = new UnityEvent(); /// /// Emitted when an Interactor stops touching the Interactable. /// [DocumentedByXml] public UnityEvent Untouched = new UnityEvent(); /// /// Emitted when the Interactable is untouched for the last time by an Interactor. /// [DocumentedByXml] public UnityEvent LastUntouched = new UnityEvent(); #endregion #region Grab Events /// /// Emitted when the Interactable is grabbed for the first time by an Interactor. /// [Header("Grab Events"), DocumentedByXml] public UnityEvent FirstGrabbed = new UnityEvent(); /// /// Emitted when an Interactor grabs the Interactable. /// [DocumentedByXml] public UnityEvent Grabbed = new UnityEvent(); /// /// Emitted when an Interactor ungrabs the Interactable. /// [DocumentedByXml] public UnityEvent Ungrabbed = new UnityEvent(); /// /// Emitted when the Interactable is ungrabbed for the last time by an Interactor. /// [DocumentedByXml] public UnityEvent LastUngrabbed = new UnityEvent(); #endregion #region Restriction Settings /// /// The rule to determine what is not allowed to touch this interactable. /// [Serialized, Cleared] [field: Header("Restriction Settings"), DocumentedByXml] public RuleContainer DisallowedTouchInteractors { get; set; } /// /// The rule to determine what is not allowed to grab this interactable. /// [Serialized, Cleared] [field: DocumentedByXml] public RuleContainer DisallowedGrabInteractors { get; set; } #endregion #region Container Settings /// /// The overall container for the interactable consumers. /// [Serialized, Cleared] [field: Header("Container Settings"), DocumentedByXml] public GameObject ConsumerContainer { get; set; } [Serialized, Cleared] [field: DocumentedByXml] /// /// The for the overall collisions. /// public Rigidbody ConsumerRigidbody { get; set; } #endregion #region Reference Settings /// /// The linked . /// [Serialized] [field: Header("Reference Settings"), DocumentedByXml, Restricted] public CollisionNotifier CollisionNotifier { get; protected set; } /// /// The linked . /// [Serialized] [field: DocumentedByXml, Restricted] public GameObjectObservableList ActiveCollisions { get; protected set; } /// /// The linked Touch Internal Setup. /// [Serialized] [field: DocumentedByXml, Restricted] public TouchInteractableConfigurator TouchConfiguration { get; protected set; } /// /// The linked Grab Internal Setup. /// [Serialized] [field: DocumentedByXml, Restricted] public GrabInteractableConfigurator GrabConfiguration { get; protected set; } #endregion /// /// A collection of Interactors that are currently touching the Interactable. /// public IReadOnlyList TouchingInteractors => TouchConfiguration.TouchingInteractors; /// /// A collection of Interactors that are currently grabbing the Interactable. /// public IReadOnlyList GrabbingInteractors => GrabConfiguration.GrabbingInteractors; /// /// Determines if the grab type is set to toggle. /// public bool IsGrabTypeToggle => GrabConfiguration.IsGrabTypeToggle; /// /// Whether the Interactable is currently being touched by any valid Interactor. /// public bool IsTouched => TouchingInteractors.Count > 0; /// /// Whether the Interactable is currently being grabbed by any valid Interactor. /// public bool IsGrabbed => GrabbingInteractors.Count > 0; /// /// Attempt to grab the Interactable to the given that contains an Interactor. /// /// The GameObject that the Interactor is on. public virtual void Grab(GameObject interactor) { Grab(interactor.TryGetComponent(true, true)); } /// /// Attempt to grab the Interactable to the given Interactor. /// /// The Interactor to attach the Interactable to. public virtual void Grab(InteractorFacade interactor) { GrabConfiguration.Grab(interactor); } /// /// Attempt to ungrab the Interactable to the given that contains an Interactor. /// /// The GameObject that the Interactor is on. public virtual void Ungrab(GameObject interactor) { Ungrab(interactor.TryGetComponent(true, true)); } /// /// Attempt to ungrab the Interactable. /// /// The Interactor to ungrab from. public virtual void Ungrab(InteractorFacade interactor) { GrabConfiguration.Ungrab(interactor); } /// /// Attempt to ungrab the Interactable at a specific grabbing index. /// /// The Interactor sequence index to ungrab from. public virtual void Ungrab(int sequenceIndex = 0) { GrabConfiguration.Ungrab(sequenceIndex); } /// /// Configures any container data to the sub setup components. /// protected virtual void ConfigureContainer() { TouchConfiguration.ConfigureContainer(); GrabConfiguration.ConfigureContainer(); } /// /// Called after has been changed. /// [CalledAfterChangeOf(nameof(DisallowedTouchInteractors))] protected virtual void OnAfterDisallowedTouchInteractorsChange() { TouchConfiguration.TouchValidity.ReceiveValidity = DisallowedTouchInteractors; } /// /// Called after has been changed. /// [CalledAfterChangeOf(nameof(DisallowedGrabInteractors))] protected virtual void OnAfterDisallowedGrabInteractorsChange() { GrabConfiguration.GrabReceiver.GrabValidity.ReceiveValidity = DisallowedGrabInteractors; } /// /// Called after has been changed. /// [CalledAfterChangeOf(nameof(ConsumerContainer))] protected virtual void OnAfterConsumerContainerChange() { ConfigureContainer(); } /// /// Called after has been changed. /// [CalledAfterChangeOf(nameof(ConsumerRigidbody))] protected virtual void OnAfterConsumerRigidbodyChange() { ConfigureContainer(); } } }