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