// 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. } }