void HandleTravellers() { for (int i = 0; i < trackedTravellers.Count; i++) { PortalTraveller traveller = trackedTravellers[i]; var travellerRb = traveller.travellerRigidbody; var m = linkedPortal.transform.localToWorldMatrix * transform.worldToLocalMatrix * travellerRb.transform.localToWorldMatrix; var portalPosition = m.GetColumn(3); var portalRotation = m.rotation; Vector3 offsetFromPortal = travellerRb.position - transform.position; int portalSide = System.Math.Sign(Vector3.Dot(offsetFromPortal, transform.forward)); int portalSideOld = System.Math.Sign(Vector3.Dot(traveller.previousOffsetFromPortal, transform.forward)); // Teleport the traveller if it has crossed from one side of the portal to the other if (portalSide != portalSideOld) { var positionOld = travellerRb.position; var rotOld = travellerRb.rotation; traveller.Teleport(transform, linkedPortal.transform, portalPosition, portalRotation); traveller.graphicsClone.transform.SetPositionAndRotation(positionOld, rotOld); // Can't rely on OnTriggerEnter/Exit to be called next frame since it depends on when FixedUpdate runs linkedPortal.OnTravellerEnterPortal(traveller, portalPosition); linkedPortal.JustGotTeleportedTo(); trackedTravellers.RemoveAt(i); i--; TravellerExited.Invoke(); } else { traveller.graphicsClone.transform.SetPositionAndRotation(portalPosition, portalRotation); //UpdateSliceParams (traveller); traveller.previousOffsetFromPortal = offsetFromPortal; } } }
void OnTravellerEnterPortal(PortalTraveller traveller, Vector3 position) { if (!trackedTravellers.Contains(traveller)) { traveller.EnterPortalThreshold(); traveller.previousOffsetFromPortal = position - transform.position; trackedTravellers.Add(traveller); } }
void UpdateSliceParams(PortalTraveller traveller) { // Calculate slice normal int side = SideOfPortal(traveller.travellerRigidbody.position); Vector3 sliceNormal = transform.forward * -side; Vector3 cloneSliceNormal = linkedPortal.transform.forward * side; // Calculate slice centre Vector3 slicePos = transform.position; Vector3 cloneSlicePos = linkedPortal.transform.position; // Adjust slice offset so that when player standing on other side of portal to the object, the slice doesn't clip through float sliceOffsetDst = 0; float cloneSliceOffsetDst = 0; float screenThickness = screen.transform.localScale.z; bool playerSameSideAsTraveller = SameSideOfPortal(playerCam.transform.position, traveller.travellerRigidbody.position); if (!playerSameSideAsTraveller) { sliceOffsetDst = -screenThickness; } bool playerSameSideAsCloneAppearing = side != linkedPortal.SideOfPortal(playerCam.transform.position); if (!playerSameSideAsCloneAppearing) { cloneSliceOffsetDst = -screenThickness; } // Apply parameters for (int i = 0; i < traveller.originalMaterials.Length; i++) { traveller.originalMaterials[i].SetVector("sliceCentre", slicePos); traveller.originalMaterials[i].SetVector("sliceNormal", sliceNormal); traveller.originalMaterials[i].SetFloat("sliceOffsetDst", sliceOffsetDst); traveller.cloneMaterials[i].SetVector("sliceCentre", cloneSlicePos); traveller.cloneMaterials[i].SetVector("sliceNormal", cloneSliceNormal); traveller.cloneMaterials[i].SetFloat("sliceOffsetDst", cloneSliceOffsetDst); } }