/// <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); } }
/// <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); }