コード例 #1
0
        /// <summary>
        /// Attempts to snap a given <see cref="GameObject"/> to the snap zone.
        /// </summary>
        /// <param name="objectToSnap">The object to attempt to snap.</param>
        public virtual void Snap(GameObject objectToSnap)
        {
            if (!AllValidRules.Accepts(objectToSnap))
            {
                return;
            }

            InteractableFacade snappableInteractable = objectToSnap.TryGetComponent <InteractableFacade>(true, true);

            if (snappableInteractable == null || SnappedInteractable != null)
            {
                return;
            }

            foreach (GameObject collidingWith in snappableInteractable.Configuration.ActiveCollisions.SubscribableElements)
            {
                SnapZoneActivator activatingZone = collidingWith.GetComponent <SnapZoneActivator>();

                if (activatingZone == null)
                {
                    continue;
                }

                activatingZone.Facade.Unsnap();
                break;
            }

            if (objectToSnap.transform.position.ApproxEquals(DestinationLocation.transform.position))
            {
                objectToSnap.transform.position += Vector3.forward * InitialOffset;
            }

            SnapDroppedInteractableProcess.Receive(objectToSnap);
        }
コード例 #2
0
        /// <summary>
        /// Attempts to process any other valid snappable objects against any other potential SnapZones if their primary activating zone is snapped by another object.
        /// </summary>
        public virtual void ProcessOtherSnappablesOnSnap()
        {
            foreach (GameObject snappable in SnappableInteractables)
            {
                if (snappable == null || snappable == SnappedInteractable)
                {
                    continue;
                }

                InteractableFacade snappableInteractable = snappable.TryGetComponent <InteractableFacade>(true, true);

                if (snappableInteractable == null)
                {
                    continue;
                }

                foreach (GameObject collidingWith in snappableInteractable.Configuration.ActiveCollisions.SubscribableElements)
                {
                    SnapZoneActivator activatingZone = collidingWith.GetComponent <SnapZoneActivator>();

                    if (activatingZone == null || activatingZone == ActivationArea || activatingZone.Facade.ZoneState == SnapZoneFacade.SnapZoneState.ZoneIsActivated)
                    {
                        continue;
                    }

                    activatingZone.Facade.Configuration.GrabStateEmitter.DoIsGrabbed(snappableInteractable);
                    break;
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Cancels the attempt to activate the SnapZone upon the previous activating SnapZone becoming deactivated.
        /// </summary>
        /// <param name="activator">The colliding interactable.</param>
        /// <param name="activatingZone">The SnapZone that was previously being activated by the colliding interactable.</param>
        protected virtual void CancelAttemptReactivation(GameObject activator, SnapZoneActivator activatingZone)
        {
            ListenerKey listenerKey = new ListenerKey(activator, activatingZone);

            activatingZoneListeners.TryGetValue(listenerKey, out UnityAction <GameObject> onExitActivatingZoneListener);
            if (onExitActivatingZoneListener != null)
            {
                activatingZone.Facade.Exited.RemoveListener(onExitActivatingZoneListener);
                activatingZoneListeners.Remove(listenerKey);
            }

            currentZoneListeners.TryGetValue(listenerKey, out UnityAction <GameObject> onExitCurrentZoneListener);
            if (onExitCurrentZoneListener != null)
            {
                Facade.Exited.RemoveListener(onExitCurrentZoneListener);
                currentZoneListeners.Remove(listenerKey);
            }
        }
コード例 #4
0
        /// <summary>
        /// Attempts activate this SnapZone with the given <see cref="GameObject"/>.
        /// </summary>
        /// <param name="activator">The colliding interactable.</param>
        /// <param name="activatingZone">The SnapZone that was previously being activated by the colliding interactable.</param>
        protected virtual void AttemptReactivation(GameObject activator, SnapZoneActivator activatingZone)
        {
            InteractableFacade foundInteractable = activator.TryGetComponent <InteractableFacade>(true, true);

            if (foundInteractable != null)
            {
                foundInteractable.Configuration.ActiveCollisions.Remove(activatingZone.Facade.Configuration.ActivationArea.gameObject);
            }

            ListenerKey listenerKey = new ListenerKey(activator, activatingZone);

            activatingZoneListeners.TryGetValue(listenerKey, out UnityAction <GameObject> activatingZoneListener);
            if (activatingZoneListener != null)
            {
                activatingZone.Facade.Exited.RemoveListener(activatingZoneListener);
            }
            activatingZoneListeners.Remove(listenerKey);
            Activate(activator);
        }
        /// <summary>
        /// Determines if the given Interactable is in a Snap Zone and optionally returns the Snap Zone if it is one.
        /// </summary>
        /// <param name="interactable">The Interactable to search on.</param>
        /// <param name="snapZoneFacade">The found Snap Zone to return.</param>
        /// <returns>Whether the given Interactable is in a Snap Zone.</returns>
        public virtual bool IsInSnapZone(InteractableFacade interactable, out SnapZoneFacade snapZoneFacade)
        {
            snapZoneFacade = null;

            if (interactable == null)
            {
                return(false);
            }

            foreach (GameObject activeCollision in interactable.Configuration.ActiveCollisions.NonSubscribableElements)
            {
                SnapZoneActivator foundActivator = activeCollision.TryGetComponent <SnapZoneActivator>();
                if (foundActivator != null && foundActivator.Facade != null)
                {
                    snapZoneFacade = foundActivator.Facade;
                    break;
                }
            }

            return(snapZoneFacade != null);
        }
コード例 #6
0
        /// <summary>
        /// Attempts to activate the SnapZone if the colliding <see cref="GameObject"/> is not already activating another SnapZone.
        /// </summary>
        /// <param name="activator">The colliding interactable.</param>
        public virtual void Activate(GameObject activator)
        {
            IsActivated = false;
            TrySetInteractableFacade(activator);
            if (currentActivatingInteractable == null || Facade.Configuration.ActivationArea == null || !Facade.Configuration.CollidingObjectsList.Contains(currentActivatingInteractable.gameObject))
            {
                return;
            }

            currentActivatingInteractable.Configuration.ActiveCollisions.AddUnique(Facade.Configuration.ActivationArea.gameObject);
            invalidSnapZoneCollisions.Clear();

            foreach (GameObject collidingObject in currentActivatingInteractable.Configuration.ActiveCollisions.SubscribableElements)
            {
                if (collidingObject == null)
                {
                    continue;
                }

                SnapZoneActivator activatingZone = collidingObject.GetComponent <SnapZoneActivator>();
                if (activatingZone == null)
                {
                    continue;
                }

                if (!activatingZone.Facade.Configuration.CollidingObjectsList.Contains(currentActivatingInteractable.gameObject))
                {
                    invalidSnapZoneCollisions.Add(activatingZone.Facade.Configuration.ActivationArea.gameObject);
                    continue;
                }

                if (activatingZone == Facade.Configuration.ActivationArea)
                {
                    if (!IsActivated)
                    {
                        Facade.Configuration.EmitActivated(activator);
                    }
                    IsActivated = true;
                    Validated?.Invoke(activator);
                    ClearInvalidSnapZoneCollisions(currentActivatingInteractable, ref invalidSnapZoneCollisions);
                    break;
                }
                else
                {
                    ListenerKey listenerKey = new ListenerKey(activator, activatingZone);

                    if (!activatingZoneListeners.ContainsKey(listenerKey))
                    {
                        UnityAction <GameObject> onExitActivatingZoneListener = activatingInteractable => AttemptReactivation(activatingInteractable, activatingZone);
                        activatingZone.Facade.Exited.AddListener(onExitActivatingZoneListener);
                        activatingZoneListeners.Add(listenerKey, onExitActivatingZoneListener);
                    }

                    if (!currentZoneListeners.ContainsKey(listenerKey))
                    {
                        UnityAction <GameObject> onExitCurrentZoneListener = activatingInteractable => CancelAttemptReactivation(activatingInteractable, activatingZone);
                        Facade.Exited.AddListener(onExitCurrentZoneListener);
                        currentZoneListeners.Add(listenerKey, onExitCurrentZoneListener);
                    }
                    ClearInvalidSnapZoneCollisions(currentActivatingInteractable, ref invalidSnapZoneCollisions);
                    break;
                }
            }

            ClearInvalidSnapZoneCollisions(currentActivatingInteractable, ref invalidSnapZoneCollisions);
        }
コード例 #7
0
 public ListenerKey(GameObject interactable, SnapZoneActivator zone)
 {
     this.interactable = interactable;
     this.zone         = zone;
 }