using UnityEngine;
namespace Resources.Project.Game.Player
{
public class PlayerMovement : MonoBehaviour
{
[Header("Move")]
[SerializeField] private float sprintSpeed;
[SerializeField] private float crouchSpeed;
[SerializeField] private float moveSpeedOnGround;
[SerializeField] private float moveSpeedInAir;
[Header("Jump")]
[SerializeField] private float jumpPower;
[Header("Physic")]
[SerializeField] private float gravityScale;
[SerializeField] private float accelerationOnGround;
[SerializeField] private float accelerationInAir;
[SerializeField] private float sprintAcceleration;
[SerializeField] private float slideOnGround;
[SerializeField] private float slideInAir;
[Header("GroundCheck")]
[SerializeField] private Transform groundCheckPosition;
[SerializeField] private LayerMask groundLayerMask;
[SerializeField] private float groundCheckSphereRadius;
[Header("Rotate Target")]
[SerializeField] private Transform rotationTarget;
private CharacterController characterController;
private PlayerInputHandler playerInputHandler;
private PlayerAnimation playerAnimation;
private Vector3 velocity;
private Vector3 moveVelocity;
private Vector3 smoothVelocity;
public float Speed;
public bool IsMoving { get; private set; }
public bool IsSprinting { get; private set; }
public bool IsJumped { get; private set; }
public bool IsCrouching { get; private set; }
public bool IsGrounded { get; private set; }
public bool IsAbleToMove { get; private set; } = true;
public bool IsAbleToSprint { get; private set; } = true;
public bool IsAbleToJump { get; private set; } = true;
public bool IsAbleToCrouching { get; private set; } = true;
public void Awake()
{
characterController = GetComponent<CharacterController>();;
playerInputHandler = GetComponentInParent<PlayerInputHandler>();
playerAnimation = GetComponent<PlayerAnimation>();
playerAnimation.PlayIdleAnimation();
Speed = moveSpeedOnGround;
}
private void Update()
{
IsGrounded = Physics.CheckSphere(groundCheckPosition.position, groundCheckSphereRadius, groundLayerMask);
Move();
Sprint();
Jump();
if(IsGrounded && velocity.y < -2F)
velocity.y = -2f;
if(!IsGrounded)
velocity.y += gravityScale * Time.deltaTime;
transform.rotation = Quaternion.Euler(0F, rotationTarget.eulerAngles.y, 0F);
characterController.Move((moveVelocity + velocity) * Time.deltaTime);
}
private void Move()
{
if(!IsAbleToMove || IsCrouching)
return;
Vector3 flatVelocity = new Vector3(characterController.velocity.x, 0f, characterController.velocity.z);
IsMoving = flatVelocity.normalized.magnitude > 0.3F;
Vector3 moveDirection = playerInputHandler.MoveDirection.normalized;
float deltaSpeed = IsGrounded ? Speed : moveSpeedInAir;
float acceleration = IsGrounded ? accelerationOnGround : accelerationInAir;
float slide = IsGrounded ? slideOnGround : slideInAir;
float deltaAcceleration = moveDirection.magnitude == 0 ? slide : acceleration;
smoothVelocity = Vector3.MoveTowards(smoothVelocity, moveDirection * deltaSpeed, deltaAcceleration * deltaSpeed * Time.deltaTime);
moveVelocity = transform.TransformDirection(smoothVelocity);
if(IsGrounded)
{
if(IsMoving)
playerAnimation.PlayMoveAnimation(moveDirection.normalized);
else
playerAnimation.PlayIdleAnimation();
}
}
private void Jump()
{
IsJumped = false;
if(!IsAbleToJump)
return;
if(IsGrounded && playerInputHandler.JumpKey.IsDown)
{
velocity.y = jumpPower;
playerAnimation.PlayJumpAnimation();
IsJumped = true;
}
}
private void Sprint()
{
if(!IsAbleToSprint || IsCrouching)
return;
if(IsGrounded)
{
IsSprinting = playerInputHandler.SprintKey.IsKeep && moveVelocity.magnitude > 0.01f;
float targetSpeed = IsSprinting ? sprintSpeed : moveSpeedOnGround;
Speed = Mathf.MoveTowards(Speed, targetSpeed, sprintAcceleration * Time.deltaTime);
playerAnimation.PlaySprintAnimation(IsSprinting);
}
}
public void AddForce(Vector3 force) => characterController.Move(transform.TransformDirection(force));
}
} 평가좀
별로..
그럼 피드백 좀
@건포도극혐(222.237) 농담~
보통 이렇게 되면 단점이 동작이 많아지면 코드가 더러워진다는거임
동작 추가할 때마다 기존 동작을 다 건드려줘야하니까