コード例 #1
0
        void tryTeleport()
        {
            if (validTeleport)
            {
                // Call any events, fade screen, etc.
                BeforeTeleportFade();

                Vector3    destination = TeleportDestination.position;
                Quaternion rotation    = TeleportMarker.transform.rotation;

                // Override if we're looking at a teleport destination
                DestinationObject = _hitObject.GetComponent <TeleportDestination>();
                if (DestinationObject != null)
                {
                    destination = DestinationObject.DestinationTransform.position;

                    if (DestinationObject.ForcePlayerRotation)
                    {
                        rotation = DestinationObject.DestinationTransform.rotation;
                    }
                }

                StartCoroutine(doTeleport(destination, rotation, AllowTeleportRotation));
            }

            // We teleported, so update this value for next raycast
            validTeleport  = false;
            aimingTeleport = false;

            hideTeleport();
        }
コード例 #2
0
        void calculateParabola()
        {
            validTeleport = false;
            bool isDestination = false;

            Vector3[] segments = new Vector3[SegmentCount];

            segments[0] = teleportTransform.position;
            // Initial velocity
            Vector3 segVelocity = teleportTransform.forward * SimulationVelocity * Time.fixedUnscaledDeltaTime;

            _hitObject = null;

            for (int i = 1; i < SegmentCount; i++)
            {
                // Hit something, so assign all future segments to this segment
                if (_hitObject != null)
                {
                    segments[i] = _hitVector;
                    continue;
                }

                // Time it takes to traverse one segment of length segScale (careful if velocity is zero)
                float segTime = (segVelocity.sqrMagnitude != 0) ? SegmentScale / segVelocity.magnitude : 0;

                // Add velocity from gravity for this segment's timestep
                segVelocity = segVelocity + Physics.gravity * segTime;

                // Check to see if we're going to hit a physics object
                if (Physics.Raycast(segments[i - 1], segVelocity, out hit, SegmentScale, CollisionLayers))
                {
                    // remember who we hit
                    _hitObject = hit.collider;

                    // set next position to the position where we hit the physics object
                    segments[i] = segments[i - 1] + segVelocity.normalized * hit.distance;

                    // correct ending velocity, since we didn't actually travel an entire segment
                    segVelocity = segVelocity - Physics.gravity * (SegmentScale - hit.distance) / segVelocity.magnitude;

                    _hitAngle = Vector3.Angle(transform.up, hit.normal);

                    // Align marker to hit normal
                    TeleportMarker.transform.position = segments[i]; // hit.point;
                    TeleportMarker.transform.rotation = Quaternion.FromToRotation(TeleportMarker.transform.up, hit.normal) * TeleportMarker.transform.rotation;

                    // Snap to Teleport Destination
                    DestinationObject = _hitObject.GetComponent <TeleportDestination>();
                    if (DestinationObject != null)
                    {
                        isDestination = true;
                        TeleportMarker.transform.position = DestinationObject.transform.position;
                        TeleportMarker.transform.rotation = DestinationObject.transform.rotation;
                    }

                    _hitVector = segments[i];
                }
                // Nothing hit, continue line by settings next segment to the last
                else
                {
                    segments[i] = segments[i - 1] + segVelocity * segTime;
                }
            }

            validTeleport = _hitObject != null;

            // Make sure teleport location is valid
            // Destination Targets ignore checks
            if (validTeleport && !isDestination)
            {
                // Angle too steep
                if (_hitAngle > MaxSlope)
                {
                    validTeleport = false;
                }

                // Hit a grabbable object
                if (_hitObject.GetComponent <Grabbable>() != null)
                {
                    validTeleport = false;
                }

                // Hit a restricted zone
                if (_hitObject.GetComponent <InvalidTeleportArea>() != null)
                {
                    validTeleport = false;
                }

                // Something in the way via raycast
                if (!teleportClear())
                {
                    validTeleport = false;
                }
            }

            // Render the positions as a line
            TeleportLine.positionCount = SegmentCount;
            for (int i = 0; i < SegmentCount; i++)
            {
                TeleportLine.SetPosition(i, segments[i]);
            }

            if (!validTeleport)
            {
                _invalidFrames++;
            }
            else
            {
                _invalidFrames = 0;
            }
        }