示例#1
0
        // There character doesn't move, all of the objects around it do. Make sure the character is in the correct position
        public void Update()
        {
            Vector3    moveDirection = Vector3.zero;
            float      hitDistance   = 0;
            RaycastHit hit;

            // cast a ray to see if we are over any platforms
            if (Physics.Raycast(thisTransform.position + capsuleCollider.center, -thisTransform.up, out hit, Mathf.Infinity, platformLayer))
            {
                hitDistance = hit.distance;
                PlatformObject platform = null;
                if (!hit.transform.Equals(prevHitTransform))
                {
                    prevHitTransform = hit.transform;
                    // update the platform object
                    if (((platform = hit.transform.GetComponent <PlatformObject>()) != null) || ((platform = hit.transform.parent.GetComponent <PlatformObject>()) != null))
                    {
                        if (platform != platformObject)
                        {
                            platformObject = platform;
                            CheckForCurvedPlatform();
                        }
                    }
                }

                // we are over a platform, determine if we are on the ground of that platform
                if (hit.distance <= capsuleCollider.height / 2 + 0.0001f + pivotOffset.y)
                {
                    onGround = true;
                    // we are on the ground. Get the platform object and check to see if we are on a curve
                    // if we are sliding and the platform has a slope then stop sliding
                    if (isSliding)
                    {
                        if (platformObject != null && platformObject.slope != PlatformSlope.None)
                        {
                            StopCoroutine("DoSlide");
                            StopSlide(true);
                        }
                    }

                    // if we are jumping we either want to start jumping or land
                    if (isJumping)
                    {
                        if (isJumpPending)
                        {
                            moveDirection.y += jumpSpeed;
                            cameraController.AdjustVerticalOffset(jumpSpeed * Time.deltaTime);
                            jumpSpeed += gravity * Time.deltaTime;
                            onGround   = false;
                        }
                        else
                        {
                            isJumping    = false;
                            jumpLandTime = Time.time;
                            if (gameManager.IsGameActive())
                            {
                                playerAnimation.Run();
                            }
                            groundCollisionParticleSystem.Play();
                        }
                    }
                    else
                    {
                        // we are not jumping so our position should be the same as the hit point
                        Vector3 position = thisTransform.position;
                        position.y             = hit.point.y;
                        thisTransform.position = position + pivotOffset;
                    }
                    skipFrame = true;
                    // a hit distance of -1 means that the platform is within distance
                    hitDistance = -1;
                }
                // if we didn't hit a platform we may hit a floor
            }
            else if (Physics.Raycast(thisTransform.position + capsuleCollider.center, -thisTransform.up, out hit, Mathf.Infinity, floorLayer))
            {
                hitDistance = hit.distance;
            }

            if (hitDistance != -1)
            {
                // a platform is beneith us but it is far away. If we are jumping apply the jump speed and gravity
                if (isJumping)
                {
                    moveDirection.y += jumpSpeed;
                    cameraController.AdjustVerticalOffset(jumpSpeed * Time.deltaTime);
                    jumpSpeed += gravity * Time.deltaTime;

                    // the jump is no longer pending if we are in the air
                    if (isJumpPending)
                    {
                        isJumpPending = false;
                    }
                }
                else if (!skipFrame)
                {
                    // apply gravity if we are not jumping
                    moveDirection.y = gravity * (powerUpManager.IsPowerUpActive(PowerUpTypes.SpeedIncrease) ? 2 : 1); // the speed power up needs a little extra push
                }

                if (!skipFrame && hitDistance == 0)
                {
                    platformObject = null;
                }
                if (skipFrame)
                {
                    skipFrame = false;
                }
                else if (hitDistance != 0 && thisTransform.position.y + (moveDirection.y * Time.deltaTime) < hit.point.y)
                {
                    // this transition should be instant so ignore Time.deltaTime
                    moveDirection.y = (hit.point.y - thisTransform.position.y) / Time.deltaTime;
                }
                onGround = false;
            }

            float xStrafe = (targetPosition.x - thisTransform.position.x) * Mathf.Abs(Mathf.Cos(targetRotation.eulerAngles.y * Mathf.Deg2Rad)) / Time.deltaTime;
            float zStrafe = (targetPosition.z - thisTransform.position.z) * Mathf.Abs(Mathf.Sin(targetRotation.eulerAngles.y * Mathf.Deg2Rad)) / Time.deltaTime;

            moveDirection.x        += Mathf.Clamp(xStrafe, -horizontalSpeed, horizontalSpeed);
            moveDirection.z        += Mathf.Clamp(zStrafe, -horizontalSpeed, horizontalSpeed);
            thisTransform.position += moveDirection * Time.deltaTime;

            // Make sure we don't run into a wall
            if (Physics.Raycast(thisTransform.position + Vector3.up, thisTransform.forward, capsuleCollider.radius, wallLayer))
            {
                gameManager.GameOver(GameOverType.Wall, true);
            }

            if (!gameManager.IsGameActive())
            {
                enabled = InAir(); // keep the character active for as long as they are in the air so gravity can keep pushing them down.
            }
        }