/// <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); }
/// <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; } }
/// <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); }
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; }
/// <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); }
public override void Initialize(Teleportable t) { }
/// <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> /// 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); }
/// <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(); }
/// <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); }
/// <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); }
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; }