示例#1
0
        /// <summary>
        ///     Adds a child to the teleportable and updates components
        /// </summary>
        /// <param name="gameObject">GameObject to add</param>
        public void AddChild(GameObject gameObject)
        {
            gameObject.SetActive(!gameObject.activeSelf);
            var newObject = Instantiate(gameObject);

            gameObject.SetActive(!gameObject.activeSelf);
            newObject.transform.parent =
                SKSGeneralUtils.FindAnalogousTransform(gameObject.transform.parent, Root, Doppleganger.transform, true);
            UpdateBounds();
            InstantiateDoppleganger(newObject.transform);
        }
        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;
        }
        // Update is called once per frame
        public virtual void CustomUpdate()
        {
            if (throughPortal)
            {
                Teleport();
            }

            //Check if the gameobject this script is attached to is through a Portal
            if (!throughPortal && currentPortal &&
                SKSGeneralUtils.IsBehind(transform.position, currentPortal.Origin.position,
                                         currentPortal.Origin.forward * 1.01f))
            {
                StartCoroutine(DelayedTeleport());
            }
            else if (throughPortal && currentPortal &&
                     SKSGeneralUtils.IsBehind(transform.position, currentPortal.Target.Origin.position,
                                              currentPortal.Target.Origin.forward * 1.01f))
            {
                StartCoroutine(DelayedUnTeleport());
            }
        }
示例#4
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);
            }
        }
示例#5
0
        /// <summary>
        ///     Render a Renderer frame, assuming that the camera is in front of the Renderer and all conditions are met.
        /// </summary>
        /// <param name="camera">The camera rendering the Renderer</param>
        /// <param name="nearClipVerts">The vertices of the camera's near clip plane</param>
        private void TryRender(Camera camera, Vector3[] nearClipVerts)
        {
            if (!Target || !Rendering)
            {
                return;
            }
            //bool isVisible = false;
            var isVisible = false;

            //Check if the camera itself is behind the Renderer, even if the frustum isn't.

            if (!IsMirror)
            {
                if (!SKSGeneralUtils.IsBehind(camera.gameObject.transform.position, Origin.position, Origin.forward))
                {
                    isVisible = true;
                }
                else
                {
                    foreach (var v in nearClipVerts)
                    {
                        if (!SKSGeneralUtils.IsBehind(v, Origin.position, Origin.forward))
                        {
                            isVisible = true;
                            break;
                        }
                    }
                }
            }
            else
            {
                if (SKSGeneralUtils.IsBehind(camera.gameObject.transform.position, Origin.position, Origin.forward))
                {
                    isVisible = true;
                }
                else
                {
                    foreach (var v in nearClipVerts)
                    {
                        if (SKSGeneralUtils.IsBehind(v, Origin.position, Origin.forward))
                        {
                            isVisible = true;
                            break;
                        }
                    }
                }
            }


            if (isVisible || CheeseActivated != -1)
            {
                EffectCamera.RenderIntoMaterial(
                    camera, RenderMaterial,
                    MeshRenderer, Target.MeshRenderer,
                    MeshFilter.mesh, !NonObliqueOverride ? CheeseActivated == -1 : false,
                    Is3D, IsMirror, IsLowqEffect);
            }

            MeshRenderer.GetPropertyBlock(_seamlessRecursionBlock);
            SeamlessRecursionRenderer.SetPropertyBlock(_seamlessRecursionBlock);
        }
示例#6
0
 /// <summary>
 ///     Remove child from teleportable
 /// </summary>
 /// <param name="gameObject"></param>
 public void RemoveChild(GameObject gameObject)
 {
     Destroy(SKSGeneralUtils.FindAnalogousTransform(gameObject.transform, Root, Doppleganger.transform)
             .gameObject);
 }
示例#7
0
        private void FixedUpdate()
        {
            if (!gameObject.activeInHierarchy)
            {
                return;
            }
            UpdateBounds();

            if (!FastMoving)
            {
                return;
            }

            if (!AttachedCollider || !AttachedCollider.attachedRigidbody)
            {
                return;
            }
            RaycastHit[] hits;
            var          velocity  = AttachedCollider.attachedRigidbody.velocity.normalized;
            var          magnitude = velocity.magnitude * Time.deltaTime;

            if (!Bullet)
            {
                hits = Physics.BoxCastAll(transform.position - velocity * magnitude, AttachedCollider.bounds.extents,
                                          velocity, Quaternion.identity,
                                          AttachedCollider.attachedRigidbody.velocity.magnitude * Time.deltaTime, ~0,
                                          QueryTriggerInteraction.Collide);
#if UNITY_EDITOR
                DebugDrawExtensions.DrawBoxCastBox(transform.position - velocity * magnitude,
                                                   AttachedCollider.bounds.extents, Quaternion.identity, velocity,
                                                   AttachedCollider.attachedRigidbody.velocity.magnitude * Time.deltaTime * 2f, Color.white);
#endif
            }
            else
            {
                hits = Physics.BoxCastAll(transform.position - velocity * magnitude, AttachedCollider.bounds.extents,
                                          velocity, Quaternion.identity,
                                          AttachedCollider.attachedRigidbody.velocity.magnitude * Time.deltaTime * 2f, ~0,
                                          QueryTriggerInteraction.Collide);
#if UNITY_EDITOR
                DebugDrawExtensions.DrawBoxCastBox(transform.position - velocity * magnitude,
                                                   AttachedCollider.bounds.extents, Quaternion.identity, velocity,
                                                   AttachedCollider.attachedRigidbody.velocity.magnitude * Time.deltaTime * 2f, Color.white);
#endif
            }

            var predictedCollide = false;
            foreach (var h in hits)
            {
                if (!h.collider)
                {
                    continue;
                }
                var portal = h.collider.GetComponent <Portal>();
                if (!portal)
                {
                    PortalTrigger trigger;
                    if (trigger = h.collider.GetComponent <PortalTrigger>())
                    {
                        portal = trigger.portal;
                    }
                }

                if (portal)
                {
                    //Force the next physics step to tick on the bullet
                    if (Bullet)
                    {
                        if (SKSGeneralUtils.IsBehind(
                                transform.position + AttachedCollider.attachedRigidbody.velocity * Time.deltaTime,
                                portal.Origin.position,
                                portal.Origin.forward))
                        {
                            transform.position += AttachedCollider.attachedRigidbody.velocity * Time.deltaTime;
                            PortalUtils.TeleportObject(gameObject, portal.Origin, portal.ArrivalTarget, Root);
                        }
                    }

                    portal.E_OnTriggerStay(AttachedCollider);
                    predictedCollide = true;
                    fastMovingAdded  = true;
                }

                /*
                 * if (portal) {
                 *  if (PortalUtils.IsBehind(transform.position + velocity, portal.Origin.position,
                 *      portal.Origin.forward)) {
                 *      portal.E_OnTriggerEnter(AttachedCollider);
                 *      predictedCollide = true;
                 *  }
                 *
                 * }*/
            }


            if (!predictedCollide && fastMovingAdded)
            {
                if (CurrentPortal != null && AttachedCollider)
                {
                    CurrentPortal.E_OnTriggerExit(AttachedCollider);
                    fastMovingAdded = false;
                }
            }
        }
示例#8
0
        /// <summary>
        ///     Instantiate the Doppeganger recursively. Makes a fully copy of all visual
        ///     components of the object, discarding non-visual components.
        /// </summary>
        /// <param name="currentLevel">Current level to target</param>
        private void InstantiateDoppleganger(Transform currentLevel)
        {
            var other = SKSGeneralUtils.FindAnalogousTransform(currentLevel, Doppleganger.transform, Root, true);

            //Remove the MainCamera tag if it's been erroniously copied.
            if (currentLevel.tag.Equals("MainCamera"))
            {
                currentLevel.tag = Keywords.Tags.Untagged;
            }

            currentLevel.gameObject.name = currentLevel.gameObject.name;
            foreach (var component in currentLevel.GetComponents <Component>())
            {
                if (component is Teleportable)
                {
                    component.SafeDestroyComponent();
                }
                //Copies Transforms for later updating
                else if (component is Transform)
                {
                    if (other)
                    {
                        if (!Transforms.ContainsKey(other))
                        {
                            Transforms.Add(other, (Transform)component);
                        }
                    }
                    else
                    {
                        Destroy(currentLevel.gameObject);
                        break;
                    }
                }
                else if (component is Renderer)
                {
                    if (component is SkinnedMeshRenderer)
                    {
                        SkinnedRenderers.Add(component as SkinnedMeshRenderer);
                    }

                    var meshRenderer = component as MeshRenderer;
                    if (meshRenderer != null)
                    {
                        var otherRend = other.GetComponent <MeshRenderer>();
                        if (!Renderers.ContainsKey(otherRend))
                        {
                            Renderers[otherRend] = meshRenderer;
                        }
                        //Adds colliders to list for collision ignoring upon Portal entry
                    }
                    else
                    {
                        var otherRend = other.GetComponent <Renderer>();
                        if (!Renderers.ContainsKey(otherRend))
                        {
                            Renderers[otherRend] = (Renderer)component;
                        }
                        //Adds colliders to list for collision ignoring upon Portal entry
                    }
                }
                else if (component is Collider)
                {
                    if (!component.GetComponent <TeleportablePhysExclude>())
                    {
                        var c = other.GetComponent <Collider>();
                        if (!_colliders.ContainsKey(c.GetInstanceID()))
                        {
                            _colliders.Add(c.GetInstanceID(), c);
                        }
#if SKS_VR
                        else
                        {
                            //Fix for VRTK double-genning body colliders for no reason

                            currentLevel.gameObject.transform.SetParent(null);
                            c.enabled = false;
                            int key = c.GetInstanceID();
                            _colliders[key].enabled   = false;
                            c.isTrigger               = true;
                            _colliders[key].isTrigger = true;
                            DestroyImmediate(_colliders[key].gameObject);
                            DestroyImmediate(currentLevel.gameObject);
                            continue;
                        }
#endif
                    }

                    if (StripColliders && component)
                    {
                        component.SafeDestroyComponent();
                    }
                }
                else if (component is Rigidbody)
                {
                    if (StripRigidbodies)
                    {
                        component.SafeDestroyComponent();
                    }
                }
                else if (component is Joint)
                {
                    if (StripJoints)
                    {
                        component.SafeDestroyComponent();
                    }
                }
                else if (component is MonoBehaviour)
                {
                    //Handling of teleportable scripts
                    if (component is TeleportableScript)
                    {
                        TeleportableScripts.Add(other.GetComponent <TeleportableScript>());
                    }

                    if (!StripScripts)
                    {
                        ((MonoBehaviour)component).enabled = true;
                    }
                    else
                    {
                        component.SafeDestroyComponent();
                    }
                    //Nonspecific setup copying
                }
                else
                {
                    var system = component as ParticleSystem;
                    if (system != null)
                    {
                        var otherSystem = other.GetComponent <ParticleSystem>();
                        system.randomSeed = otherSystem.randomSeed;
                        system.time       = otherSystem.time;
                    }
                    else if (component is MeshFilter || component is Light)
                    {
                        //nothin to do
                    }
                    else
                    {
                        component.SafeDestroyComponent();
                    }
                }
            }

            if (other)
            {
                currentLevel.gameObject.SetActive(other.gameObject.activeSelf);
            }

            foreach (Transform t in currentLevel)
            {
                InstantiateDoppleganger(t);
            }
        }
示例#9
0
        private void InstantiateDoppleganger(Transform currentLevel)
        {
            Transform other = SKSGeneralUtils.FindAnalogousTransform(currentLevel, Doppleganger.transform, root, true);

            if (currentLevel.tag.Equals("MainCamera"))
            {
                currentLevel.tag = "Untagged";
            }
            currentLevel.gameObject.name = currentLevel.gameObject.name;
            foreach (Component component in currentLevel.GetComponents <Component>())
            {
                if (component is Teleportable)
                {
                    component.SafeDestroyComponent();
                }
                //Copies Transforms for later updating
                else if (component is Transform)
                {
                    if (other)
                    {
                        if (!Transforms.ContainsKey(other))
                        {
                            Transforms.Add(other, (Transform)component);
                        }
                    }
                    else
                    {
                        Destroy(currentLevel.gameObject);
                        break;
                    }
                }
                else if (component is Renderer)
                {
                    if (component is SkinnedMeshRenderer)
                    {
                        SkinnedRenderers.Add(component as SkinnedMeshRenderer);
                    }
                    if (component is Renderer)
                    {
                        if (!Renderers.ContainsKey((Renderer)component))
                        {
                            Renderers[other.GetComponent <Renderer>()] = (Renderer)component;
                        }
                        //Adds colliders to list for collision ignoring upon Portal entry
                    }
                }
                else if (component is Collider)
                {
                    if (!component.GetComponent <TeleportablePhysExclude>())
                    {
                        Collider c = other.GetComponent <Collider>();
                        if (!Colliders.ContainsKey(c.GetInstanceID()))
                        {
                            Colliders.Add(c.GetInstanceID(), c);
                        }
                        else
                        {
                            //Fix for VRTK double-genning body colliders for no reason
                            currentLevel.gameObject.transform.SetParent(null);
                            c.enabled = false;
                            Colliders[c.GetInstanceID()].enabled = false;
                            c.isTrigger = true;
                            Colliders[c.GetInstanceID()].isTrigger = true;
                            DestroyImmediate(Colliders[c.GetInstanceID()].gameObject);
                            DestroyImmediate(currentLevel.gameObject);
                            return;
                        }
                    }
                    if (StripColliders && component)
                    {
                        component.SafeDestroyComponent();
                    }
                }
                else if (component is Rigidbody)
                {
                    if (StripRigidbodies)
                    {
                        component.SafeDestroyComponent();
                    }
                }
                else if (component is Joint)
                {
                    if (StripJoints)
                    {
                        component.SafeDestroyComponent();
                    }
                }
                else if (component is MonoBehaviour)
                {
                    //Handling of teleportable scripts
                    if (component is TeleportableScript)
                    {
                        TeleportableScripts.Add(other.GetComponent <TeleportableScript>());
                    }

                    if (!StripScripts)
                    {
                        if (component != null)
                        {
                            ((MonoBehaviour)component).enabled = true;
                        }
                    }
                    else
                    {
                        component.SafeDestroyComponent();
                    }
                    //Nonspecific setup copying
                }
                else if (component is MeshFilter || component is ParticleSystem || component is Light)
                {
                    //nothin to do
                }
                else
                {
                    component.SafeDestroyComponent();
                }
            }

            if (other)
            {
                currentLevel.gameObject.SetActive(other.gameObject.activeSelf);
            }

            foreach (Transform t in currentLevel)
            {
                InstantiateDoppleganger(t);
            }
        }