예제 #1
0
        /// <summary>
        /// Removes a teleportable from the portal area
        /// </summary>
        /// <param name="teleportScript">teleportable to remove</param>
        private void RemoveTeleportable(Teleportable teleportScript)
        {
            if (!teleportScript || !NearTeleportables.Contains(teleportScript))
            {
                return;
            }
            if (teleportScript.RemovedLastFrame)
            {
                return;
            }
            teleportScript.RemovedLastFrame = true;
            if (!NonObliqueOverride)
            {
                teleportScript.SetClipPlane(Vector3.zero, Vector3.zero, teleportScript.Renderers.Keys);
                teleportScript.SetClipPlane(Vector3.zero, Vector3.zero, teleportScript.Renderers.Values);
            }

            UpdateDopplegangers();
            NearTeleportables.Remove(teleportScript);

            if (NearTeleportables.Count < 1)
            {
                SetBufferWallActive(false);
            }

            teleportScript.LeavePortal();
            //teleportScript.ResetDoppleganger();
            teleportScript.ResumeAllCollision(this);
        }
예제 #2
0
        /// <summary>
        ///     Removes a teleportable from the portal area
        /// </summary>
        /// <param name="teleportable">teleportable to remove</param>
        private void RemoveTeleportable(Teleportable teleportable)
        {
            if (!teleportable || teleportable.RemovedLastFrame)
            {
                return;
            }
            if (!NearTeleportables.Contains(teleportable))
            {
                return;
            }
            teleportable.RemovedLastFrame = true;

            if (!NonObliqueOverride)
            {
                teleportable.SetClipPlane(Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero);
            }


            NearTeleportables.Remove(teleportable);
            UpdateDopplegangers();

            if (NearTeleportables.Count < 1)
            {
                SetBufferWallActive(false);
            }

            teleportable.LeavePortal(this);

            teleportable.CollisionManager.ResumeCollisionsForKey(this);

            if (teleportable == GlobalPortalSettings.PlayerTeleportable)
            {
                _headInPortalTrigger = false;
            }
        }
예제 #3
0
        /// <summary>
        /// All collsision methods are externed to another script
        /// </summary>
        public void E_OnTriggerEnter(Collider col)
        {
            Physics.IgnoreCollision(col, PortalCollider);
            Rigidbody teleportableBody = col.attachedRigidbody;

            if (!teleportableBody)
            {
                return;
            }
            Teleportable teleportScript = teleportableBody.GetComponent <Teleportable>();

            AddTeleportable(teleportScript);
        }
예제 #4
0
        public virtual void Initialize(Teleportable teleportable)
        {
            this.teleportable = teleportable;
            originalParent    = transform.parent;
            try {
                otherTransform = SKSGeneralUtils.FindAnalogousTransform(transform, teleportable.Root,
                                                                        teleportable.Doppleganger.transform, true);
                otherTransformParent = otherTransform.parent;
            }
            catch (NullReferenceException e) {
                Debug.LogError("Teleportablescript on " + name + "had a problem:" + e.Message);
            }

            originalPosition = transform.localPosition;
            originalRotation = transform.localRotation;
            originalScale    = transform.localScale;
        }
예제 #5
0
        /// <summary>
        /// Removes primed objects from the queue if they move away from the Portal
        /// </summary>
        public void E_OnTriggerExit(Collider col)
        {
            Rigidbody teleportableBody = col.attachedRigidbody;

            if (!teleportableBody)
            {
                return;
            }
            Teleportable teleportScript = teleportableBody.GetComponent <Teleportable>();

            if (col == HeadCollider)
            {
                _headInPortalTrigger = false;
            }

            RemoveTeleportable(teleportScript);
        }
예제 #6
0
 public override void Initialize(Teleportable t)
 {
 }
예제 #7
0
        /// <summary>
        ///     Teleports the given teleportable, making passthrough and image effects seamless.
        /// </summary>
        /// <param name="teleportable">Teleportable to teleport</param>
        /// <param name="col">Associated Collider</param>
        private void TryTeleportTeleporable(Teleportable teleportable, Collider col)
        {
            if (!SKSGeneralUtils.IsBehind(teleportable.TeleportableBounds.center, Origin.position, Origin.forward) ||
                teleportable.VisOnly)
            {
                return;
            }
            //if (!PortalUtils.IsBehind(col.transform.position, Origin.position, Origin.forward) || teleportable.VisOnly) return;
            if (teleportable.TeleportedLastFrame)
            {
                return;
            }

            teleportable.TeleportedLastFrame = true;
            RemoveTeleportable(teleportable);

            //Makes objects not with invisible buffer bounds in the case of portals being too close
            foreach (var c in BufferWall)
            {
#if !DISABLE_PHYSICS_IGNORE
                teleportable.CollisionManager.IgnoreCollision(this, c, true);
#endif
            }

            var targetPortal = (Portal)Target;


            teleportable.StartTeleport(this);

            PortalUtils.TeleportObject(teleportable.Root.gameObject, Origin, ArrivalTarget, teleportable.Root, null,
                                       true,
                                       !SKSGlobalRenderSettings.NonScaledRenderers);

            targetPortal.FixedUpdate();
            teleportable.Teleport(this, targetPortal);

            targetPortal.PhysicsPassthrough.UpdatePhysics();
            var teleportableColliders = teleportable.CollisionManager.Colliders.ToArray();
            targetPortal.PhysicsPassthrough.ForceRescanOnColliders(teleportableColliders);
            PhysicsPassthrough.ForceRescanOnColliders(teleportableColliders);
            targetPortal.E_OnTriggerStay(col);

            teleportable.FinishTeleport(this);

            if (teleportable == GlobalPortalSettings.PlayerTeleportable)
            {
            }

            targetPortal.UpdateDopplegangers(true);
            UpdateDopplegangers(true);

            //Un-register head as being in portal trigger to prevent flash
            if (teleportable == GlobalPortalSettings.PlayerTeleportable)
            {
                _headInPortalTrigger = false;
                targetPortal.UpdateDopplegangers(true);
                targetPortal.IncomingCamera();
                CheeseActivated = -1;
                //Resets the vis depth of the Portal volume
                if (!Is3D)
                {
                    transform.localScale = new Vector3(1f, 1f, FudgeFactor);
                }
            }

            Rigidbody body;
            if ((body = col.attachedRigidbody) && SKSGlobalRenderSettings.PhysStyleB)
            {
                var colliderEnabled      = PortalCollider.enabled;
                var otherColliderEnabled = targetPortal.PortalCollider.enabled;

                PortalCollider.enabled = true;
                targetPortal.PortalCollider.enabled = true;

                var portalBody = PortalCollider.attachedRigidbody;
                var targetBody = targetPortal.PortalCollider.attachedRigidbody;

                PortalCollider.enabled = colliderEnabled;
                targetPortal.PortalCollider.enabled = otherColliderEnabled;

                if (portalBody != null &&
                    targetBody != null)
                {
                    var relativeVelocity = Quaternion.Inverse(portalBody.rotation) * portalBody.velocity;
                    relativeVelocity += Quaternion.Inverse(targetBody.rotation) * targetBody.velocity;
                    relativeVelocity  = targetBody.rotation * relativeVelocity;
                    body.AddForce(relativeVelocity, ForceMode.Impulse);
                }
            }

            if (OnTeleportObject != null)
            {
                OnTeleportObject.Invoke(teleportable, (Portal)Target);
            }

            if (targetPortal.OnObjectArrived != null)
            {
                targetPortal.OnObjectArrived.Invoke(teleportable, this);
            }
        }
예제 #8
0
        /// <summary>
        ///     Attempt to add a teleportableScript to the nearteleportables group
        /// </summary>
        /// <param name="teleportable">the script to add</param>
        public bool AddTeleportable(Teleportable teleportable)
        {
            if (NearTeleportables.Contains(teleportable))
            {
                return(true);
            }
            if (!Target ||
                !Enterable ||
                !teleportable ||
                !teleportable.initialized ||
                teleportable.AddedLastFrame)
            {
                return(false);
            }


            SetBufferWallActive(true);

            teleportable.AddedLastFrame = true;
            teleportable.EnableDoppleganger();

            NearTeleportables.Add(teleportable);

            //Ignores collision with rear objects
            var checkedVerts = PortalUtils.BackCheckVerts(MeshFilter.mesh);

            //Ignore collision with the Portal itself
#if !DISABLE_PHYSICS_IGNORE
            teleportable.CollisionManager.IgnoreCollision(this, PortalCollider, true, true);
            teleportable.CollisionManager.IgnoreCollision(this, ((Portal)Target).PortalCollider, true, true);
#endif
            //Ignores rear-facing colliders
            var          ray = new Ray();
            RaycastHit[] hit;

            //Enables the buffer wall if it is disabled
            foreach (Transform tran in BufferWallObj.transform)
            {
                var c = tran.GetComponent <Collider>();
                c.enabled = true;
            }

            var ignoredColliders = new HashSet <Collider>();

            //Raycast back
            foreach (var v in checkedVerts)
            {
                ray.origin    = transform.TransformPoint(v) + transform.forward * 0.01f;
                ray.direction = -transform.forward;

                hit = Physics.RaycastAll(ray, 1 * transform.parent.localScale.z, ~0, QueryTriggerInteraction.Collide);
                Debug.DrawRay(ray.origin, -transform.forward * transform.parent.localScale.z, Color.cyan, 3);
                if (hit.Length <= 0)
                {
                    continue;
                }
                foreach (var h in hit)
                {
                    //Never ignore collisions with Physics Passthrough Duplicates
                    var t = h.collider.gameObject.GetComponent <Teleportable>();
                    if (h.collider.gameObject.CompareTag(Keywords.Tags.PhysicDupe) ||
                        t != null)
                    {
                        continue;
                    }

                    if (h.collider.transform.parent && transform.parent && h.collider.transform.parent.parent &&
                        transform.parent.parent)
                    {
#if !DISABLE_PHYSICS_IGNORE
                        if (h.collider.transform.parent.parent != transform.parent.parent)
                        {
                            teleportable.CollisionManager.IgnoreCollision(this, h.collider);
                            ignoredColliders.Add(h.collider);
                        }
#endif
                    }
                    else
                    {
#if !DISABLE_PHYSICS_IGNORE
                        teleportable.CollisionManager.IgnoreCollision(this, h.collider);
                        ignoredColliders.Add(h.collider);
#endif
                    }
                }
            }

            var downCheckVerts = this.DownCheckVerts();
            foreach (var v in downCheckVerts)
            {
                ray.origin    = Origin.TransformPoint(v) - transform.forward * 0.01f;
                ray.direction = -transform.up;
                hit           = Physics.RaycastAll(ray, transform.parent.localScale.y + 0.3f, ~0,
                                                   QueryTriggerInteraction.Collide);
                Debug.DrawRay(ray.origin, -transform.up * transform.parent.localScale.y, Color.red, 3);
                if (hit.Length <= 0)
                {
                    continue;
                }
                foreach (var h in hit)
                {
                    if (ignoredColliders.Contains(h.collider))
                    {
                        FloorSegment.enabled = true;
                        goto TERRAIN_INTERSECTION;
                    }
                }
            }

TERRAIN_INTERSECTION:

            teleportable.EnterPortal(this);

            UpdateDopplegangers();

            return(true);
        }
예제 #9
0
        /// <summary>
        /// Attempt to add a teleportableScript to the nearteleportables group
        /// </summary>
        /// <param name="teleportScript">the script to add</param>
        private void AddTeleportable(Teleportable teleportScript)
        {
            if (!TargetPortal)
            {
                return;
            }
            if (!teleportScript || NearTeleportables.Contains(teleportScript))
            {
                return;
            }
            if (teleportScript.AddedLastFrame)
            {
                return;
            }

            SetBufferWallActive(true);

            teleportScript.AddedLastFrame = true;
            teleportScript.EnableDoppleganger();

            NearTeleportables.Add(teleportScript);

            //Ignores collision with rear objects
            Vector3[] checkedVerts = PortalUtils.ReferenceVerts(MeshFilter.mesh);

            //Ignore collision with the Portal itself
            teleportScript.IgnoreCollision(this, PortalCollider);
            teleportScript.IgnoreCollision(this, TargetPortal.PortalCollider);

            //Ignores rear-facing colliders
            Ray ray = new Ray();

            RaycastHit[] hit;

            //Enables the buffer wall if it is disabled
            foreach (Transform tran in BufferWallObj.transform)
            {
                Collider c = tran.GetComponent <Collider>();
                c.enabled = true;
            }

            foreach (Vector3 v in checkedVerts)
            {
                ray.origin    = transform.TransformPoint(v) + transform.forward * 0.01f;
                ray.direction = -transform.forward;
                hit           = Physics.RaycastAll(ray, 1 * transform.parent.localScale.z, ~0, QueryTriggerInteraction.Collide);
                Debug.DrawRay(ray.origin, -transform.forward * transform.parent.localScale.z, Color.cyan, 10);
                if (hit.Length <= 0)
                {
                    continue;
                }
                foreach (RaycastHit h in hit)
                {
                    //Never ignore collisions with teleportables
                    //Never ignore collisions with teleportables

                    if (h.collider.gameObject.tag.Equals("PhysicsPassthroughDuplicate") ||
                        h.collider.gameObject.GetComponent <Teleportable>() != null)
                    {
                        continue;
                    }

                    if (h.collider.transform.parent && transform.parent && h.collider.transform.parent.parent && transform.parent.parent)
                    {
                        if (h.collider.transform.parent.parent != transform.parent.parent)
                        {
                            teleportScript.IgnoreCollision(this, h.collider);
                        }
                    }
                    else
                    {
                        teleportScript.IgnoreCollision(this, h.collider);
                    }
                }
            }

            //todo: Remove this when multiple simultaneous portal intersection gets added
            //TargetPortal.RemoveTeleportable(teleportScript);
            UpdateDopplegangers();
        }
예제 #10
0
        /// <summary>
        /// Teleports the given teleportable, making passthrough and image effects seamless.
        /// </summary>
        /// <param name="teleportable">Teleportable to teleport</param>
        /// <param name="col">Associated Collider</param>
        private void TryTeleportTeleporable(Teleportable teleportable, Collider col)
        {
            if (!PortalUtils.IsBehind(teleportable.TeleportableBounds.center, Origin.position, Origin.forward) || teleportable.VisOnly)
            {
                return;
            }
            //if (!PortalUtils.IsBehind(col.transform.position, Origin.position, Origin.forward) || teleportable.VisOnly) return;
            if (teleportable.TeleportedLastFrame)
            {
                return;
            }

            teleportable.TeleportedLastFrame = true;
            RemoveTeleportable(teleportable);
            //Makes objects not with invisible buffer bounds in the case of portals being too close
            foreach (Collider c in BufferWall)
            {
                teleportable.IgnoreCollision(this, c, true);
            }

            PortalUtils.TeleportObject(teleportable.root.gameObject, Origin, ArrivalTarget, teleportable.root, null, true,
                                       !SKSGlobalRenderSettings.NonScaledRenderers);
            TargetPortal.FixedUpdate();
            teleportable.Teleport();
            //TargetPortal.UpdateDopplegangers();
            TargetPortal.PhysicsPassthrough.UpdatePhysics();
            //teleportable.SetClipPlane(Vector3.zero, Vector3.zero, teleportable.Renderers.Keys);

            TargetPortal.PhysicsPassthrough.ForceRescanOnColliders(teleportable.Colliders.Values);

            PhysicsPassthrough.ForceRescanOnColliders(teleportable.Colliders.Values);
            TargetPortal.E_OnTriggerStay(col);

            //TargetPortal.UpdateDopplegangers(true);

            if (teleportable == GlobalPortalSettings.PlayerTeleportable)
            {
                TargetPortal.UpdateDopplegangers(true);
                TargetPortal.IncomingCamera();
                _cheeseActivated     = -1;
                _headInPortalTrigger = false;
                //Resets the vis depth of the Portal volume
                if (!Is3D)
                {
                    transform.localScale = new Vector3(1f, 1f, FudgeFactor);
                }
            }

            //teleportable.EnableDoppleganger();
            //teleportable.SetClipPlane();
            //Applies relative velocity
            if (!SKSGlobalRenderSettings.PhysStyleB)
            {
                return;
            }

            Rigidbody body;

            if (body = col.attachedRigidbody)
            {
                bool colliderEnabled      = PortalCollider.enabled;
                bool otherColliderEnabled = TargetPortal.PortalCollider.enabled;

                PortalCollider.enabled = true;
                TargetPortal.PortalCollider.enabled = true;

                Rigidbody portalBody = PortalCollider.attachedRigidbody;
                Rigidbody targetBody = TargetPortal.PortalCollider.attachedRigidbody;

                PortalCollider.enabled = colliderEnabled;
                TargetPortal.PortalCollider.enabled = otherColliderEnabled;

                if ((portalBody) != null &&
                    (targetBody) != null)
                {
                    Vector3 relativeVelocity = Quaternion.Inverse(portalBody.rotation) * portalBody.velocity;
                    relativeVelocity += Quaternion.Inverse(targetBody.rotation) * targetBody.velocity;
                    relativeVelocity  = targetBody.rotation * relativeVelocity;
                    body.AddForce(relativeVelocity, ForceMode.Impulse);
                }
            }
            TargetPortal.UpdateDopplegangers(true);
            UpdateDopplegangers(true);
        }
예제 #11
0
        /// <summary>
        /// Checks if objects are in Portal, and teleports them if they are. Also handles player entry.
        /// </summary>
        /// <param name="col"></param>
        public void E_OnTriggerStay(Collider col)
        {
            if (!TargetPortal)
            {
                return;
            }

            Rigidbody teleportableBody = col.attachedRigidbody;

            if (!teleportableBody)
            {
                return;
            }
            //todo: cache these
            Teleportable teleportScript = teleportableBody.GetComponent <Teleportable>();

            AddTeleportable(teleportScript);
            if (!Enterable || !teleportScript || !teleportScript.initialized)
            {
                return;
            }

            if (teleportScript == GlobalPortalSettings.PlayerTeleportable)
            {
                _headInPortalTrigger = true;
                //teleportScript = PlayerTeleportable;
            }


            //Updates clip planes for disappearing effect
            if (!NonObliqueOverride)
            {
                teleportScript.SetClipPlane(Origin.position, Origin.forward /* (1 + transform.localScale.z)*/ + (Origin.forward * 0.01f), teleportScript.Renderers.Keys);
                teleportScript.SetClipPlane(ArrivalTarget.position, -ArrivalTarget.forward, teleportScript.Renderers.Values);
            }

            WakeBufferWall();

            //Makes objects collide with invisible buffer bounds
            foreach (Collider c in BufferWall)
            {
                teleportScript.AddCollision(this, c);
            }

            //Makes objects collide with invisible buffer bounds
            foreach (Collider c in TargetPortal.BufferWall)
            {
                teleportScript.IgnoreCollision(this, c, true);
            }

            if (SKSGlobalRenderSettings.PhysicsPassthrough)
            {
                //Makes objects collide with objects on the other side of the Portal
                foreach (Collider c in PassthroughColliders.Values)
                {
                    teleportScript.AddCollision(this, c);
                }
            }


            //Passes Portal info to teleport script
            teleportScript.SetPortalInfo(this);

            //Enables Doppleganger
            teleportScript.EnableDoppleganger();

            //Checks if object should be teleported
            TryTeleportTeleporable(teleportScript, col);
        }
예제 #12
0
        IEnumerator DelayedSetup()
        {
            GameObject headObj = null;

            while (headObj == null)
            {
                Transform bodytransform = VRTK_DeviceFinder.HeadsetCamera();
                if (bodytransform)
                {
                    headObj = bodytransform.gameObject;
                }
                yield return(new WaitForEndOfFrame());
            }

            AutomaticCameraLayerSet layerSet = headObj.AddComponent <AutomaticCameraLayerSet>();

            layerSet.ExcludedLayers = new List <string>();
            layerSet.ExcludedLayers.Add("PortalOnly");
            layerSet.ExcludedLayers.Add("PortalPlaceholder");
            layerSet.ExcludedLayers.Add("RenderExclude");


            GameObject bodyObj = null;

            while (bodyObj == null)
            {
                Transform bodytransform = VRTK_DeviceFinder.PlayAreaTransform();
                if (bodytransform)
                {
                    bodyObj = bodytransform.gameObject;
                }
                yield return(new WaitForEndOfFrame());
            }


            bodyObj.transform.position = transform.position;

            yield return(new WaitForSeconds(2f));

            Teleportable teleportable = headObj.AddComponent <Teleportable>();

            teleportable.enabled  = false;
            teleportable.Root     = transform;
            teleportable.IsActive = true;
            teleportable.VisOnly  = false;
            teleportable.enabled  = true;
            //teleportable.SpecialRoot = true;


            Collider col;

            if (!(col = headObj.GetComponent <Collider>()))
            {
                col = headObj.AddComponent <BoxCollider>();
                ((BoxCollider)col).size = new Vector3(0.25f, 0.25f, 0.25f);
                col.isTrigger           = true;
            }

            Rigidbody headRB = null;

            if (!(headRB = headObj.GetComponent <Rigidbody>()))
            {
                headRB = headObj.AddComponent <Rigidbody>();
            }
            headRB.isKinematic = true;


            PlayerTeleportable playerTeleportable = headObj.AddComponent <PlayerTeleportable>();

            SelfRightingPlayer selfRight = bodyObj.AddComponent <SelfRightingPlayer>();

            selfRight.moveSpeed = 4;
        }