namespace Tilia.Interactions.PointerInteractors { using System; using Tilia.Interactions.Interactables.Interactables; using Tilia.Interactions.Interactables.Interactors; using UnityEngine; using UnityEngine.Events; using Zinnia.Cast; using Zinnia.Data.Attribute; using Zinnia.Extension; using Zinnia.Rule; /// /// The public interface into the DistanceGrabber Prefab. /// public class DistanceGrabberFacade : MonoBehaviour { /// /// Defines the event with the . /// [Serializable] public class UnityEvent : UnityEvent { } #region Interaction Settings [Header("Interaction Settings")] [Tooltip("The InteractorFacade to grab to.")] [SerializeField] private InteractorFacade interactor; /// /// The to grab to. /// public InteractorFacade Interactor { get { return interactor; } set { interactor = value; if (this.IsMemberChangeAllowed()) { OnAfterInteractorChange(); } } } [Tooltip("An optional source to get the internal pointer to follow. If one isn't provided then the Interactor will be used.")] [SerializeField] private GameObject followSource; /// /// An optional source to get the internal pointer to follow. If one isn't provided then the will be used. /// public GameObject FollowSource { get { return followSource; } set { followSource = value; if (this.IsMemberChangeAllowed()) { OnAfterFollowSourceChange(); } } } [Tooltip("The time in which it will take the Interactable to transition to the Interactor.")] [SerializeField] private float transitionDuration; /// /// The time in which it will take the Interactable to transition to the Interactor. /// public float TransitionDuration { get { return transitionDuration; } set { transitionDuration = value; if (this.IsMemberChangeAllowed()) { OnAfterTransitionDurationChange(); } } } [Tooltip("The time in which to delay being able to distance grab again after ungrabbing.")] [SerializeField] private float ungrabDelay; /// /// The time in which to delay being able to distance grab again after ungrabbing. /// public float UngrabDelay { get { return ungrabDelay; } set { ungrabDelay = value; if (this.IsMemberChangeAllowed()) { OnAfterUngrabDelayChange(); } } } #endregion #region Pointer Settings [Header("Pointer Settings")] [Tooltip("Determines which targets are valid to initiate the distance grab.")] [SerializeField] private RuleContainer targetValidity; /// /// Determines which targets are valid to initiate the distance grab. /// public RuleContainer TargetValidity { get { return targetValidity; } set { targetValidity = value; if (this.IsMemberChangeAllowed()) { OnAfterTargetValidityChange(); } } } [Tooltip("Determines the rules for the pointer RayCast.")] [SerializeField] private PhysicsCast raycastRules; /// /// Determines the rules for the pointer RayCast. /// public PhysicsCast RaycastRules { get { return raycastRules; } set { raycastRules = value; if (this.IsMemberChangeAllowed()) { OnAfterRaycastRulesChange(); } } } #endregion #region Grab Events /// /// Emitted before the grab occurs. /// [Header("Grab Events")] public UnityEvent BeforeGrabbed = new UnityEvent(); /// /// Emitted if the grab occurrence is canceled. /// public UnityEvent GrabCanceled = new UnityEvent(); /// /// Emitted after the grab occurs. /// public UnityEvent AfterGrabbed = new UnityEvent(); #endregion #region Reference Settings [Header("Reference Settings")] [Tooltip("The linked Internal Setup.")] [SerializeField] [Restricted] private DistanceGrabberConfigurator configuration; /// /// The linked Internal Setup. /// public DistanceGrabberConfigurator Configuration { get { return configuration; } set { configuration = value; } } #endregion /// /// The current being distance grabbed. /// public virtual InteractableFacade CurrentInteractable => Configuration.Grabber.Interactable; /// /// Clears . /// public virtual void ClearInteractor() { if (!this.IsValidState()) { return; } Interactor = default; } /// /// Clears . /// public virtual void ClearFollowSource() { if (!this.IsValidState()) { return; } FollowSource = default; } /// /// Clears . /// public virtual void ClearTargetValidity() { if (!this.IsValidState()) { return; } TargetValidity = default; } /// /// Clears . /// public virtual void ClearRaycastRules() { if (!this.IsValidState()) { return; } RaycastRules = default; } /// /// Called after has been changed. /// protected virtual void OnAfterInteractorChange() { Configuration.ConfigureInteractor(); } /// /// Called after has been changed. /// protected virtual void OnAfterFollowSourceChange() { Configuration.ConfigureInteractor(); } /// /// Called after has been changed. /// protected virtual void OnAfterTransitionDurationChange() { Configuration.ConfigurePropertyApplier(); } /// /// Called after has been changed. /// protected virtual void OnAfterUngrabDelayChange() { Configuration.ConfigurePropertyApplier(); } [Obsolete("Use `OnAfterUngrabDelayChange` instead.")] protected virtual void OnAfterConfigureReactivatePointerTimerChange() { OnAfterUngrabDelayChange(); } /// /// Called after has been changed. /// protected virtual void OnAfterTargetValidityChange() { Configuration.ConfigurePointerRules(); } /// /// Called after has been changed. /// protected virtual void OnAfterRaycastRulesChange() { Configuration.ConfigurePointerRules(); } } }