public void Simulate( CharacterController characterController, PlayerFoley playerFoley, PlayerInput input) { var transform = this.transform; float deltaTime = Time.deltaTime; bool isJumping = !characterController.isGrounded; bool jumpStart = false; if (!isJumping && input.jump) { _jumpingScalar = -jumping.force; jumpStart = true; } else if ((_jumpingScalar += deltaTime * jumping.dampSpeed) >= jumping.gravityFactor) { _jumpingScalar = jumping.gravityFactor; } float frictionFactor = isJumping ? 0.99f : 0.1f; var absMove = new Vector2(Mathf.Abs(input.move.x), Mathf.Abs(input.move.y)); var signMove = new Vector2(Mathf.Sign(input.move.x), Mathf.Sign(input.move.y)); var wantSpeed = Vector2.one; wantSpeed *= Mathf.Lerp(locomotion.walkSpeed, locomotion.runSpeed, input.run); wantSpeed = Vector2.Scale(wantSpeed, signMove); wantSpeed = Vector2.Lerp(_movingSpeed, wantSpeed, isJumping ? 0f : deltaTime * 10f); wantSpeed = Vector2.Scale( wantSpeed, Vector2.Lerp( absMove, new Vector2( Mathf.Approximately(input.move.x, 0f) ? 0f : 1f, Mathf.Approximately(input.move.y, 0f) ? 0f : 1f), input.run)); _movingSpeed = Vector2.Lerp(wantSpeed, wantSpeed * frictionFactor, !isJumping ? 0f : deltaTime); float angularSpeed = 360f * deltaTime * Mathf.Lerp(looking.lookSpeed, looking.runLookSpeed, input.run); float lookX = input.look.x; float lookY = input.look.y * Mathf.Sign(input.move.y); _lookingAngles.x = _lookingAngles.x + lookX * angularSpeed; _lookingAngles.y = _lookingAngles.y + lookY * angularSpeed; _lookingAngles.x = Angles.Unwind( Mathf.Clamp( Angles.ToRelative(_lookingAngles.x), looking.pitchLimitMin, looking.pitchLimitMax)); UpdateLooking(transform, deltaTime); UpdateMoving(transform, deltaTime, characterController); float walkSpeedSqr = locomotion.walkSpeed * locomotion.walkSpeed; float runSpeedSqr = locomotion.runSpeed * locomotion.runSpeed; float speedSqr = _movingSpeed.sqrMagnitude; float speedScalar = (speedSqr - walkSpeedSqr) / (runSpeedSqr - walkSpeedSqr); if (speedScalar < Mathf.Epsilon) { speedScalar = 0f; } int hadFeetPlanted = _feetPlanted; isJumping = !characterController.isGrounded; // check again after moving if (jumpStart) { _jumpSpeedScalar = speedScalar; } UpdateFootPlanting(transform, playerFoley, speedSqr, speedScalar, isJumping); if (jumpStart) { playerFoley.OnJump(); } else if (hadFeetPlanted == 0 && _feetPlanted != 0) { playerFoley.OnLand(); } playerFoley.breathingIntensity = isJumping ? 1f : speedScalar; playerFoley.playerJumping = jumpStart || _feetPlanted == 0; }