/** * Called once per Update AND once per FixedUpdate, this checks to see if an * object near the portal has gone through it and whisks it away if it has. */ protected void TrackForTeleport(PhysicalTrackingInfo info) { //What side of the portal is it on? var pos = transform.InverseTransformPoint(info.center.position); var isInFront = pos.z <= 0; info.hasBeenInFront = info.hasBeenInFront || isInFront; //If it was once in front of us and now it's behind we should look into teleporting it. if (info.hasBeenInFront && !isInFront) { var obj = info.root; //Is teleporting something we should do? if (!Application.isPlaying || !physicsOptions.teleportOnTouch || !destination) { return; } //Have we recently teleported? (Unity will call OnTriggerStay an additional frame sometimes, even after //an item has been teleported away.) if (recentTeleports.ContainsKey(obj)) { return; } TeleportObjectThroughPortal(obj); } }
/** Teleports the given item to the other side of the portal, altering rotation, position, speed, etc. */ public void TeleportObjectThroughPortal(Transform obj) { //Debug.Log(FrameStamp + "Teleport " + obj.name); Debug.DrawRay(obj.transform.position, obj.transform.forward, Color.blue, 1); var teleportController = obj.GetComponent <TeleportController>(); if (teleportController) { var doIt = teleportController.BeforeTeleport(this); if (!doIt) { return; } } //If we have a ShadowClone for this object (we probably do), swap the location of the object and the clone. //This helps cover the one-frame gap before the return portal (if there is one) creates its own clone to cover the shape. PhysicalTrackingInfo trackingInfo = null; if (physicalTrackingInfo.TryGetValue(obj, out trackingInfo) && trackingInfo.clone) { var clone = trackingInfo.clone; clone.DestroyNextFixedFrame(); clone.transform.position = obj.position; clone.transform.rotation = obj.rotation; //Now that we're teleporting, remove the "been in front of this portal" flag. trackingInfo.hasBeenInFront = false; } //teleport to other side TeleportRelativeToDestination(obj.transform); Debug.DrawRay(obj.transform.position, obj.transform.forward, Color.green, 1); //Don't teleport this again for a few fixed updates recentTeleports[obj] = teleportCooldownFrames * Time.fixedDeltaTime + Time.fixedTime; StartCoroutine(CooldownTeleports()); //kick off job to remove this "hot" teleport //also add teleport offset, if any obj.transform.position += destination.rotation * physicsOptions.teleportOffset; //Deal with any other state that has to handle being teleported. RotateComponents(obj); //todo: dissolve RotateComponents into a bunch of auto-added TeleportControllers if (teleportController) { teleportController.AfterTeleport(this); } }
public void OnTriggerEnter(Collider otherCollider) { //Debug.Log(FrameStamp + "OnTriggerEnter " + otherCollider.name + " at " + otherCollider.transform.position.y); var root = FindTeleportRoot(otherCollider.transform); PhysicalTrackingInfo trackingInfo; if (physicalTrackingInfo.TryGetValue(root.transform, out trackingInfo)) { //+1 collision, also make sure we can look up the info by out transform trackingInfo.collisionCount += 1; physicalTrackingInfo[otherCollider.transform] = trackingInfo; return; } //If there's a camera on the object, make sure we teleport based on the camera center, not the movement center var center = root; var childCamera = root.GetComponentInChildren <Camera>(); if (childCamera) { center = childCamera.transform; } trackingInfo = new PhysicalTrackingInfo { root = root, center = center, collisionCount = 1 }; physicalTrackingInfo[root.transform] = trackingInfo; physicalTrackingInfo[otherCollider.transform] = trackingInfo; // var inFront = Vector3.Dot(other.transform.positionhasBeenInFront) // trackingInfo.lastDistance = PortalMath.DistanceFromPointToPlane(transform.position, transform.forward, other.transform.position); //mimic the object on the other side trackingInfo.clone = ShadowClone.Create(root.transform, this); }
public void OnTriggerEnter(Collider otherCollider) { //Debug.Log(FrameStamp + "OnTriggerEnter " + otherCollider.name + " at " + otherCollider.transform.position.y); var root = FindTeleportRoot(otherCollider.transform); PhysicalTrackingInfo trackingInfo; if (physicalTrackingInfo.TryGetValue(root.transform, out trackingInfo)) { //+1 collision, also make sure we can look up the info by out transform trackingInfo.collisionCount += 1; physicalTrackingInfo[otherCollider.transform] = trackingInfo; return; } //If there's a camera on the object, make sure we teleport based on the camera center, not the movement center var center = root; var childCamera = root.GetComponentInChildren<Camera>(); if (childCamera) center = childCamera.transform; trackingInfo = new PhysicalTrackingInfo { root = root, center = center, collisionCount = 1 }; physicalTrackingInfo[root.transform] = trackingInfo; physicalTrackingInfo[otherCollider.transform] = trackingInfo; // var inFront = Vector3.Dot(other.transform.positionhasBeenInFront) // trackingInfo.lastDistance = PortalMath.DistanceFromPointToPlane(transform.position, transform.forward, other.transform.position); //mimic the object on the other side trackingInfo.clone = ShadowClone.Create(root.transform, this); }