private void HandlerCharacterMovement() { Vector3 worldspaceMoveInput = logicObject.transform.TransformVector(input.GetMoveInput()); if (isOnGround) { Vector3 targetVelocity = maxSpeedOnGround * worldspaceMoveInput * speedModify; targetVelocity = GetDirectionReorientedOnSlope(targetVelocity.normalized, groundNormal) * targetVelocity.magnitude; characterVelocity = Vector3.Lerp(characterVelocity, targetVelocity, movementSharpnessOnGround * BattleApplicationBooter.DeltaTime); //jump if (isOnGround && input.GetJumpInput()) { characterVelocity = new Vector3(characterVelocity.x, 0f, characterVelocity.z); characterVelocity += Vector3.up * jumpForce; lastJumpTime = BattleGameLoop.Time; isOnGround = false; groundNormal = Vector3.up; } } //in air else { characterVelocity += worldspaceMoveInput * accelerationSpeedInAir * BattleApplicationBooter.DeltaTime; float verticalVelocity = characterVelocity.y; Vector3 horizontalVelocity = Vector3.ProjectOnPlane(characterVelocity, Vector3.up); horizontalVelocity = Vector3.ClampMagnitude(horizontalVelocity, maxSpeedInAir); characterVelocity = horizontalVelocity + (Vector3.up * verticalVelocity); characterVelocity += Vector3.down * gravity * BattleApplicationBooter.DeltaTime; } Vector3 bottomBeforeMove = GetCharacterBottomHemisphere(); Vector3 topBeforeMove = GetCharacterTopHemisphere(); controller.Move(characterVelocity * BattleApplicationBooter.DeltaTime); lastImpactSpeed = Vector3.zero; if (Physics.CapsuleCast(bottomBeforeMove, topBeforeMove, controller.radius, characterVelocity.normalized, out RaycastHit hit, characterVelocity.magnitude * BattleApplicationBooter.DeltaTime, -1, QueryTriggerInteraction.Ignore)) { lastImpactSpeed = characterVelocity; characterVelocity = Vector3.ProjectOnPlane(characterVelocity, hit.normal); } }