New Input System과 기본적인 플레이어 움직임에 관한 글은 아래 블로그를 참고

2025.03.04 - [Unity] - [Unity] New Input System 으로 플레이어 움직이기

 

[Unity] New Input System 으로 플레이어 움직이기

1. New Input System2. New Input System 사용방법3. PlayerController  스크립트4. PlayerInput 컴포넌트📝 New Input System이란?                                                                          Unit

youcheachae.tistory.com

 


📝 플레이어 Jump                                                                                    

 

상단의 링크에서 작성한 PlayerMove 스크립트에서 추가로 작성해주었다.

    // ....
    #region 플레이어 점프

    public void OnJump(InputAction.CallbackContext context) 
    { 
        // 한번 눌리면 
        if(context.phase == InputActionPhase.Started) 
        {
            playerRb.velocity = Vector3.zero;
            playerRb.AddForce(Vector3.up * 5f , ForceMode.Impulse);
        }
    }
    #endregion
    // ....

  OnJump()

             PlayInput컴포넌트에서 입력 발생 시 리턴되는 콜백을 받아오기 위한 함수 작성

             매개변수를 InputAction.CallbackContext로 콜백을 받아온다

             입력이 눌렸을 때, 플레이어의 Vector3.Up방향(0,1,0)으로 , Addforce 해준다. 

 

  컴포넌트의 Event → Player  Jump Aciont에 (+) 버튼으로 추가해 준다

  Player 오브젝트를 드래그해서 넣고, PlayerController스크립트의 OnJump메서드를 추가한다 

 

📝 발생한 문제                                                                                    

열심히 스페이스바를 누르고 있지만 플레이어에 Addforce가 적용되지 않는 모습이다.

 

🔖 해결시도

1. Mass를 줄이기 / 늘리기 

            Mass는 오브젝트 질량 이기 때문에 질량을 줄이면 느리게 떨어지고, 늘리면 빨리 떨어질 거라 생각했다.

:

하지만 Mass를 변경해도 떨어지는 속도가 변하지 않았다. 

 

2. 중력 Scale을 수정 

             Edit → Project Setting Physics의 Gravity를 -24 정도까지 줄여봤다. 

: 하지만 이것 또한 플레이어가 떨어지는 속도가 변하지 않았다. 

 

3. 테스트로 만들어놓은 큐브와 컴포넌트 하나하나 비교해 보기....

: 테스트용 큐브와 플레이어의 차이는 PlayerController밖에 없는데,

혹시 여기서 문제인가...?! 싶어서 코드를 다시 뜯어봤다.

 

 

- 그 당시 PlayerMove() 코드 

private void PlayerMove() 
{
    Vector3 dir = transform.forward * moveVector.y + transform.right * moveVector.x;
    dir *= speed;
    playerRb.velocity = dir;
}

: 해당 코드에서 , y값의 속력을 지정해 주는 부분이 없다!!

그래서 y의 속력이 항상 0으로 설정되고 , 그래서 Gravity값과 Mass를 아무리 수정해도 변화가 없었던 것.............

 

- 해결 방법

🔖 dir의 y는 현재 물리엔진에서 계산되고 있는 중력이나 점프 등으로 발생한 y 방향의 속도를 유지하기 위해서 playerRB.velocity.y로 설정해 주면 된다.

    dir.y = playerRB.velocity.y;

 

y 속도를 생각하지 못한 내 실수였던 것....


: 상단의 링크에서 작성한 코드 PlayerMove()에 대해 추가적인 설명을 하고 넘어가려 한다.

전체적인 코드는 상단의 링크를 참고!

private void Move() 
{
    Vector3 dir = transform.forward * curMoveInput.y + transform.right * curMoveInput.x;
    dir *= _moveSpeed;
    dir.y = playerRB.velocity.y;    

    playerRB.velocity = dir;
}

  curMoveInput은 Vector2 타입으로, x와 y 밖에 없다.

 Vector2에서 움직일 때, 플레이어 기준 앞 / 뒤로 움직이면 y 값이 변화한다. 좌 / 우로 움직이면 x 값이 변화한다.

              y가 양수면 앞쪽으로 이동
              y가 음수면 뒤쪽으로 이동
              x가 양수면 오른쪽으로 이동
              x가 음수면 왼쪽으로 이동

 Vector3에서 움직일 때, 플레이어 기준 앞 / 뒤로 움직이면 z 값이 변화한다. 좌 / 우로 움직이면 x 값이 변화한다.

 

위에서 바라봤을 때 Vector2와 Vector3의 축 변화

 

  플레이어 기준 앞/뒤 움직임이 발생하면 플레이어 앞쪽(forward)과 y값을 곱하고, 좌/우 움직임이 발생하면 플레이어의 오른쪽 (right)과 x 값을 곱해서 가야 할 방향을 나타낸다.

  y는 위에서 설명한 대로, 현재 물리엔진에서 계산되고 있는 중력이나 점프 등으로 발생한 y 방향의 속도를 유지하기 위해서 playerRB.velocity.y로 설정해 주면 된다.

 

📝 마우스에 따른 플레이어 회전 / 카메라 회전                                                                               

접근방식

마우스를 회전하면, 플레이어의 x회전과 y 회전을 변경시켜야 된다고 생각했다. 

하지만 플레이어의 x값 회전을 하면 플레이어의 콜라이더가 땅에 박히거나 충돌 나는 문제가 발생할 것 같았다. 

: 콜라이더가 땅에 박힌다....


즉 , 마우스를 회전하면 

1. 플레이어의 y 회전 값 (좌, 우)이 변경되어야 한다.

2. 카메라의 x 회전 값 (상, 하)이 변경되어야 한다.

 

 

- 구체적인 코드

[Header("===Rotate===")]
[SerializeField] private Vector2 mouseDelta;        // 마우스 움직임 델타
[SerializeField] private float currentY;            // 현재 회전 상태 Y
[SerializeField] private float rotationBoundary = 80f;
[SerializeField] private float sensitivity;

private void LateUpdate()
{
    RotateCamera();
}

private void RotateCamera()
{
    // 플레이어는 rotation의 y값만 바껴야한다
    // 카메라는 rotation의 x값만 바껴야 한다

    currentY += mouseDelta.y * sensitivity;

    float newY = Mathf.Clamp(currentY, -rotationBoundary , rotationBoundary) ;

    // 카메라 회전 
    cameraTrs.localEulerAngles = new Vector3( -newY, 0, 0);

    // 플레이어 회전 
    transform.eulerAngles += new Vector3(0, mouseDelta.x * sensitivity, 0);
}

public void OnRotateCamera(InputAction.CallbackContext context)
{
    // Delta값 :
    // 화면의 중앙을 (0, 0) 기준으로
    // 마우스를 빠르게 움직일수록 절대값이 커짐
    //      마우스를 오른쪽으로 빠르게 이동: (15, 0)
    //      마우스를 왼쪽으로 천천히 이동: (-2, 0)
    mouseDelta = context.ReadValue<Vector2>();
    // Debug.Log($"Mouse Delta: {mouseDelta}");
}

  OnRotateCamera()

             context.ReadValue <Vector2>()로 마우스 움직임에 관한 Vector2 값을 mouseDelta 변수에 저장한다. 

  RotateCamera()

            카메라 회전을 계산하기 위해서 입력받은 mouseDelta값의 y에 sensitivity값을 곱해서 저장한다.

            카메라 회전 (위, 아래)는 너무 큰 값이 들어가면 360도 돌 수 있기 때문에 임시로 -80 ~ 80까지 값으로 설정했다.

            localEulerAngles를 사용해서 회전값을 적용한다. 

                      □ 카메라는 현재 Player 하위에 있기 때문에 local 회전값을 변경시켜 준다 

                       카메라의 회전값을 변경하면 (-) 값으로 들어가서 코드상에서 (- ) 값을 넣어준다

            플레이어 회전 (좌, 우)는 mouseDelta값의 x로 설정한다.

 


📝 플레이어 움직임/점프/카메라 회전 결과 

원하던 움직임이 잘 나타나는 것을 확인할 수 있다. 


https://github.com/kimYouChae/Sparta_OnlyUp

 

 

 

 

+ Recent posts