示例#1
0
    void RecalculateOffset(bool isInsideLongTunnel)
    {
        if (isInsideLongTunnel)
        {
            //player is inside the long tunnel, so
            //cameras of the short tunnel must work normally
            shortS.offset = Vector3.zero;
            shortN.offset = Vector3.zero;
        }
        else
        {
            /*
             * player is outside the long tunnel, (maybe in the area of the short tunnel, looking through it)
             * so cameras of the short tunnel must work different.
             *
             * this is because... when player is looking THROUGH the short tunnel (but seeing the long one), there's this
             * explicit problem: the other side of the tunnel is not "playing" in the back panel of the long tunnel,
             * because player is not in the long tunnel, so I have to fake as he was inside, so the short-tunnel cameras
             * take the back of the short-side and not elsewhere
             *
             * Normally, the camera in the other side mimics the player's movement but in the OTHER side.
             * But, in this particular case, player and the "other" camera are in the SAME side: they're both in the
             * short-tunnel side, but acting as if player were inside the long tunnel (in the other side)
             *
             * This is the only time when I have to adjust the normal placement of cameras
             */

            Vector3 longTunnelLongitude = longTunnelSouthPortal.position - longTunnelNorthPortal.position;
            Vector3 distShortSouth      = playerCamera.position - shortTunnelSouthPortal.position;
            Vector3 oldPosition         = shortTunnelNorthPortal.position + playerCamera.position - longTunnelNorthPortal.position;
            Vector3 newPosition         = shortTunnelNorthPortal.position + longTunnelLongitude + distShortSouth;
            shortN.offset = newPosition - oldPosition;

            Vector3 distShortNorth = playerCamera.position - shortTunnelNorthPortal.position;
            oldPosition   = shortTunnelSouthPortal.position + playerCamera.position - longTunnelSouthPortal.position;
            newPosition   = shortTunnelSouthPortal.position - longTunnelLongitude + distShortNorth;
            shortS.offset = newPosition - oldPosition;
        }

        shortS.LateUpdate();
        shortN.LateUpdate();
        longS.LateUpdate();
        longN.LateUpdate();
    }
示例#2
0
    void Teleport(Transform objectToTeleport, bool forceTeleportAndNoEvent = false, bool entering = true)
    {
        if ((objectToTeleport.position - transform.position).magnitude > 5)
        {
            return;
        }

        //which side of the portal is the object?
        if (!forceTeleportAndNoEvent)
        {
            float dotProduct = Vector3.Dot(transform.up, objectToTeleport.position - transform.position);
            if ((entering && dotProduct < 0) || (!entering && dotProduct > 0))
            {
                //wrong side. Don't teleport.
                teleportPlayerOnExit = false;
                return;
            }
        }
        //good side, continue


        // Teleport the object
        if (otherScript != null)
        {
            otherScript.teleportPlayerOnExit = true;
        }

        Vector3   oldPosition = objectToTeleport.position;
        Vector3   rbOffset    = Vector3.zero;
        Rigidbody rb          = objectToTeleport.GetComponent <Rigidbody>();

        if (rb != null)
        {
            rbOffset = rb.position - transform.position;
        }


        //position
        objectToTeleport.position = reciever.parent.TransformPoint(
            transform.parent.InverseTransformPoint(objectToTeleport.position)
            );

        //rotation
        Quaternion rot  = reciever.parent.rotation * Quaternion.Inverse(transform.parent.rotation);
        Quaternion rot2 = rot * Quaternion.Inverse(objectToTeleport.rotation);

        objectToTeleport.Rotate(
            (objectToTeleport.CompareTag("Player") ? rot2 : rot).eulerAngles.x,
            rot.eulerAngles.y,
            (objectToTeleport.CompareTag("Player") ? rot2 : rot).eulerAngles.z
            );

        //velocity (if object has rigidbody)
        if (rb != null)
        {
            rb.velocity = reciever.parent.TransformDirection(
                transform.parent.InverseTransformDirection(rb.velocity)
                );
            rb.position = transform.position + rbOffset; //not entirely necessary
        }



        if (objectToTeleport.CompareTag("Player"))
        {
            //player has crossed. If using clones, may be necessary to swap clones and originals (see documentation)
            if (setup.clones.useClones && setup.clones.whichOneHasRb == portalSetup.WhichOneHasRb.playerSide)
            {
                int howManyOnTheOtherSide = otherScript.originals.Count;
                SwapSidesOfClonesOnThisSide(originals.Count);
                otherScript.SwapSidesOfClonesOnThisSide(howManyOnTheOtherSide);
            }

            //refresh camera position before rendering, in order to avoid flickering
            otherScript.cameraScript.LateUpdate();
            cameraScript.LateUpdate();


            /*
             * If you need to do something to your player when it's teleporting, this is when.
             * See online documentation about controller (pipasjourney.com/damianGonzalez/portals/#controller)
             * and how to adapt Unity's Rigidbody First Person Controller to skewed portals
             */
        }


        //finally, fire event
        if (!forceTeleportAndNoEvent)
        {
            portalEvents.teleport?.Invoke(setup.groupId, transform.parent, reciever.parent, objectToTeleport, oldPosition, objectToTeleport.position);
        }
    }