void CheckGround() { if (groundTransform == null) { ResetGround(); } if (isOnMovingPlatform) { Physics.SyncTransforms(); //NOTE(Brian): This should move the character with the moving platform Vector3 newGroundWorldPos = groundTransform.TransformPoint(lastLocalGroundPosition); movingPlatformSpeed = Vector3.Distance(newGroundWorldPos, transform.position); transform.position = newGroundWorldPos; } Transform transformHit = CastGroundCheckingRays(); if (transformHit != null) { if (groundTransform == transformHit) { bool groundHasMoved = (transformHit.position != groundLastPosition || transformHit.rotation != groundLastRotation); if (!characterPosition.RepositionedWorldLastFrame() && groundHasMoved) { isOnMovingPlatform = true; CommonScriptableObjects.playerIsOnMovingPlatform.Set(true); Physics.SyncTransforms(); lastLocalGroundPosition = groundTransform.InverseTransformPoint(transform.position); } } else { groundTransform = transformHit; } } else { ResetGround(); } if (groundTransform != null) { groundLastPosition = groundTransform.position; groundLastRotation = groundTransform.rotation; } isGrounded = groundTransform != null && groundTransform.gameObject.activeInHierarchy; }
internal void LateUpdate() { deltaTime = Mathf.Min(deltaTimeCap, Time.deltaTime); if (transform.position.y < minimumYPosition) { SetPosition(characterPosition.worldPosition); return; } velocity.x = 0f; velocity.z = 0f; velocity.y += gravity * deltaTime; bool previouslyGrounded = isGrounded; if (!isJumping || velocity.y <= 0f) { CheckGround(); } if (isGrounded) { isJumping = false; velocity.y = gravity * deltaTime; // to avoid accumulating gravity in velocity.y while grounded } else if (previouslyGrounded && !isJumping) { lastUngroundedTime = Time.time; } if (Utils.isCursorLocked && characterForward.HasValue()) { // Horizontal movement var speed = movementSpeed * (isSprinting ? runningSpeedMultiplier : 1f); transform.forward = characterForward.Get().Value; var xzPlaneForward = Vector3.Scale(cameraForward.Get(), new Vector3(1, 0, 1)); var xzPlaneRight = Vector3.Scale(cameraRight.Get(), new Vector3(1, 0, 1)); Vector3 forwardTarget = Vector3.zero; if (characterYAxis.GetValue() > 0) { forwardTarget += xzPlaneForward; } if (characterYAxis.GetValue() < 0) { forwardTarget -= xzPlaneForward; } if (characterXAxis.GetValue() > 0) { forwardTarget += xzPlaneRight; } if (characterXAxis.GetValue() < 0) { forwardTarget -= xzPlaneRight; } forwardTarget.Normalize(); velocity += forwardTarget * speed; CommonScriptableObjects.playerUnityEulerAngles.Set(transform.eulerAngles); } bool jumpButtonPressedWithGraceTime = jumpButtonPressed && (Time.time - lastJumpButtonPressedTime < 0.15f); if (jumpButtonPressedWithGraceTime) // almost-grounded jump button press allowed time { bool justLeftGround = (Time.time - lastUngroundedTime) < 0.1f; if (isGrounded || justLeftGround) // just-left-ground jump allowed time { Jump(); } } bool movingPlatformMovedTooMuch = Vector3.Distance(lastPosition, transform.position) > movingPlatformAllowedPosDelta; if (isOnMovingPlatform && !characterPosition.RepositionedWorldLastFrame() && movingPlatformMovedTooMuch) { ResetGround(); // As the character has already been moved faster-than-we-want, we reposition it characterController.transform.position = lastPosition; } if (characterController.enabled) { //NOTE(Brian): Transform has to be in sync before the Move call, otherwise this call // will reset the character controller to its previous position. SceneController.i.physicsSyncController.Sync(); characterController.Move(velocity * deltaTime); } SetPosition(characterPosition.UnityToWorldPosition(transform.position)); if ((DCLTime.realtimeSinceStartup - lastMovementReportTime) > PlayerSettings.POSITION_REPORTING_DELAY) { ReportMovement(); } if (isOnMovingPlatform) { lastLocalGroundPosition = groundTransform.InverseTransformPoint(transform.position); } }