コード例 #1
0
    private PortalUser _portalUser; //###:TODO - really need a list or map of these, so multiple objects can be colliding with the portal at once (e.g,. large rectangle entres but does not teleport thorugh portal; then sphere enters)
    void FixedUpdate()              //https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html "FixedUpdate should be used instead of Update when dealing with Rigidbody" (so, for physical objects, you might want this)
    {
        if (_portalUser != null)
        {
            var currentDot = Vector3.Dot(transform.up, _portalUser.transform.position - transform.position);

            if (currentDot < 0) // only transport the player once they've moved across plane
            {
                // transport them to the equivalent position in the other portal
                Vector3 playerRelativeToPortalPosLocal = transform.InverseTransformPoint(_portalUser.transform.position);
                playerRelativeToPortalPosLocal.x = -playerRelativeToPortalPosLocal.x;                 //Prevent "mirroring"
                playerRelativeToPortalPosLocal.y = -playerRelativeToPortalPosLocal.y;                 //We have penerated the sender portal; need to "pop out of" the receiver portal; we use y-axis as forward as collision plane has a -90 degree rotation in X, which transposes Y, which we'd normally use, into X
                var newPosition = receiver.transform.TransformPoint(playerRelativeToPortalPosLocal);

                // And sort out new camera facing
                var receiverForwardAxis        = receiver.transform.up;                                              //Collision-plane has a rotation of -90 in X, which transposes the axes we'd normally consider
                var senderForwardAxis          = transform.up;                                                       //Collision-plane has a rotation of -90 in X, which transposes the axes we'd normally consider
                var receiverUpAxis             = receiver.transform.forward;                                         //Collision-plane has a rotation of -90 in X, which transposes the axes we'd normally consider
                var portalRotationalDifference = Quaternion.FromToRotation(senderForwardAxis, -receiverForwardAxis); //https://answers.unity.com/questions/702200/finding-the-rotation-between-two-gameobjects.html
                var newFacingDirection         = portalRotationalDifference * _portalUser.transform.forward;
                var newRotation = Quaternion.LookRotation(newFacingDirection, receiverUpAxis);

                _portalUser.Teleport(newPosition, newRotation);

                _portalUser = null;
            }
        }
    }