namespace Tilia.Interactions.Interactables.Interactors { using Tilia.Interactions.Interactables.Interactables; using UnityEngine; using Zinnia.Action; using Zinnia.Action.Collection; using Zinnia.Data.Attribute; using Zinnia.Data.Collection.List; using Zinnia.Extension; using Zinnia.Tracking.Collision.Active; using Zinnia.Tracking.Collision.Active.Event.Proxy; /// /// Sets up the Interactor Action Publisher Prefab action settings based on the provided user settings. /// public class InteractorActionPublisherConfigurator : MonoBehaviour { #region Facade Settings [Header("Facade Settings")] [Tooltip("The public interface facade.")] [SerializeField] [Restricted] private InteractorActionPublisherFacade facade; /// /// The public interface facade. /// public InteractorActionPublisherFacade Facade { get { return facade; } set { facade = value; } } #endregion #region Reference Settings [Header("Reference Settings")] [Tooltip("The ActionObservableList that contains the Action collection that can be linked to the InteractorActionFacade.SourceAction.")] [SerializeField] [Restricted] private ActionObservableList targetActions; /// /// The that contains the collection that can be linked to the . /// public ActionObservableList TargetActions { get { return targetActions; } set { targetActions = value; } } [Tooltip("The ActiveCollisionPublisher for checking valid start action.")] [SerializeField] [Restricted] private ActiveCollisionPublisher startActionPublisher; /// /// The for checking valid start action. /// public ActiveCollisionPublisher StartActionPublisher { get { return startActionPublisher; } set { startActionPublisher = value; } } [Tooltip("The ActiveCollisionPublisher for checking valid stop action.")] [SerializeField] [Restricted] private ActiveCollisionPublisher stopActionPublisher; /// /// The for checking valid stop action. /// public ActiveCollisionPublisher StopActionPublisher { get { return stopActionPublisher; } set { stopActionPublisher = value; } } [Tooltip("The ActiveCollisionsContainerEventProxyEmitter setting the active collisions on the StartActionPublisher on touch.")] [SerializeField] [Restricted] private ActiveCollisionsContainerEventProxyEmitter setOnTouchEmitter; /// /// The setting the active collisions on the on touch. /// public ActiveCollisionsContainerEventProxyEmitter SetOnTouchEmitter { get { return setOnTouchEmitter; } set { setOnTouchEmitter = value; } } [Tooltip("The ActiveCollisionPublisherEventProxyEmitter setting the active collisions on the StartActionPublisher on grab.")] [SerializeField] [Restricted] private ActiveCollisionPublisherEventProxyEmitter setOnGrabEmitter; /// /// The setting the active collisions on the on grab. /// public ActiveCollisionPublisherEventProxyEmitter SetOnGrabEmitter { get { return setOnGrabEmitter; } set { setOnGrabEmitter = value; } } #endregion /// /// The current active . /// public virtual Action ActiveAction { get; protected set; } protected virtual void OnEnable() { SetOnGrabEmitter.gameObject.SetActive(false); SetOnTouchEmitter.gameObject.SetActive(true); LinkSourceActionToTargetAction(); LinkSourceContainerToPublishers(); LinkActiveCollisions(); } protected virtual void OnDisable() { UnlinkActiveCollisions(); } /// /// Links the to the valid . /// public virtual void LinkSourceActionToTargetAction() { if (Facade == null || Facade.SourceAction == null || TargetActions == null) { return; } foreach (Action action in TargetActions.NonSubscribableElements) { action.RunWhenActiveAndEnabled(() => action.ClearSources()); if (action.GetType().IsAssignableFrom(Facade.SourceAction.GetType())) { action.RunWhenActiveAndEnabled(() => action.AddSource(Facade.SourceAction)); ActiveAction = action; } } } /// /// Links the to the payload source containers on the start and stop publishers. /// public virtual void LinkSourceContainerToPublishers() { if (Facade == null || Facade.SourceInteractor == null) { return; } StartActionPublisher.Payload.SourceContainer = Facade.SourceInteractor.gameObject; StopActionPublisher.Payload.SourceContainer = Facade.SourceInteractor.gameObject; } /// /// Links the start publisher to the . /// public virtual void LinkActiveCollisions() { if (Facade == null || Facade.SourceInteractor == null) { return; } Facade.SourceInteractor.TouchConfiguration.ExternalEmitters.Emitted.AddListener(SetOnTouchEmitter.Receive); Facade.SourceInteractor.GrabConfiguration.StartGrabbingPublisher.Published.AddListener(SetOnGrabEmitter.Receive); Facade.SourceInteractor.Grabbed.AddListener(InteractorGrabbed); Facade.SourceInteractor.Ungrabbed.AddListener(InteractorUngrabbed); } /// /// Unlinks the start publisher from the . /// public virtual void UnlinkActiveCollisions() { if (Facade == null || Facade.SourceInteractor == null) { return; } Facade.SourceInteractor.TouchConfiguration.ExternalEmitters.Emitted.RemoveListener(SetOnTouchEmitter.Receive); Facade.SourceInteractor.GrabConfiguration.StartGrabbingPublisher.Published.RemoveListener(SetOnGrabEmitter.Receive); Facade.SourceInteractor.Grabbed.RemoveListener(InteractorGrabbed); Facade.SourceInteractor.Ungrabbed.RemoveListener(InteractorUngrabbed); } /// /// Determines what to do when the Interactor grabs. /// /// The Interactable being grabbed. protected virtual void InteractorGrabbed(InteractableFacade interactable) { SetOnTouchEmitter.gameObject.SetActive(false); SetOnGrabEmitter.gameObject.SetActive(true); } /// /// Determines what to do when the Interactor ungrabs. /// /// The Interactable being grabbed. protected virtual void InteractorUngrabbed(InteractableFacade interactable) { SetOnGrabEmitter.gameObject.SetActive(false); SetOnTouchEmitter.gameObject.SetActive(true); } } }