Unity/Theory

[Unity] (New) Input System 이용한 플레이어 이동 구현

JEE_YA 2025. 3. 5. 20:46

Input System : 유니티에서 "입력"신호를 관리하는 체계.

현재는 구(Old) 버전과 신(New) 버전이 나뉘어 있으며 차이는 아래와 같다.

  • 구(Old) 버전 : Input 클래스를 통해서 코드 기반 이벤트를 만듬
  • 신(New) 버전 : 미리 버튼에 대한 이벤트 함수를 만들고, 함수 안에 기능만 추가하는 방식

 

(New) Input System

Unity 2019.1부터 제공하기 시작한 말그대로 새로운 input 시스템

다양한 플랫폼에서 빠르게 컨트롤 설정이 가능한것이 최대의 장점으로 하나의 코드를 통해 다양한 플랫폼의 입력 환경을 지원할 수 있는 것이 특징

Window > PackageManager에 들어가서 좌측 상단 Packages를 Unity Registry로 설정한 후 InputSystem을 Install 하여 사용 가능


Input System을 이용하여 캐릭터가 움직일 수 있게 해보자,

Creat > Input Actions 하여 오브젝트 생성

Edit asset 누르면 다음과 같은 창이 뜬다.

밑에는 플레이어(캐릭터)를 예시로 하여 만들어보려고 한다.

ActionMaps의 +를 눌러 Player(플레이어) 생성

Action Maps 안에 있는 Player

Player 안에는 Move(이동), Look(방향/시야), Jump(점프) 등을 설정해주려고 한다.

 

 

Move(이동) - 키보드

이동엔 방향 값(Vector2)을 받아와야하기 때문에 아래와 같이 설정

Actions의 Move > Action은 위와 같이 설정

위와 같이 설정 후 Move에 +를 눌러 Up\Down\Left\Right Composite 클릭

Move 우측 + 를 눌러 Up Down Left Right Composite 클릭

클릭해주면 Up, Down, Left, Right 네 방향이 나오게 되며 각각 방향키를 설정해주자.

Binding의 Path에 잘 맞게 선택해주면 된다.

Path에 키 설정

 

 

Look - 마우스

Look의 경우 Value 값을 받아오지만 마우스의 움직임을 받기 위해 Control Type은 Delta로 선택해준다.

Actions의 Look > Action은 위와 같이

Look의 Path는 마우스로 설정해준다.

현재까지의 세팅

일부 키는 키보드, 일부 키는 마우스로 설정해주었으며 Move와 Look을 세팅한것처럼 해주었고, 이후 저장하면 일단 끝.

InputSystem을 사용하기 위해 Using UnityEngine.InputSystem을 추가해준다.

Player 오브젝트에 PlayerInput 컴포넌트를 추가해준 후 Actions에 내가 설정했던 Input 액션(asset 파일)을 넣어주고 Event 항목을 펼치면 미리 설정한 입력 액션 목록을 확인할 수 있다.

Player 오브젝트에는 Player, PlayerController 두개의 스크립트를 컴포넌트로 넣어주었는데, PlayerController 스크립트에 액션의 내용을 작성해주고자 한다.

 


- 아래서부터는 C#스크립트 코드

 

Move

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed; 
    private Vector2 curMovementInput;
    private Rigidbody _rigidbody;

    private void Awake()
    {
        _rigidbody = GetComponent<Rigidbody>();
    }

    void Update()
    {
        Move();
    }

    void Move()
    {
        Vector3 dir = transform.forward * curMovementInput.y + transform.right * curMovementInput.x;
        dir *= moveSpeed;
        dir.y = _rigidbody.velocity.y; 

        _rigidbody.velocity = dir;
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        if(context.phase == InputActionPhase.Performed)
        {
            curMovementInput = context.ReadValue<Vector2>();
        }
        else if(context.phase == InputActionPhase.Canceled)
        {
            curMovementInput = Vector2.zero;
        }
    }
}
  • moveSpeed : 이동속도를 조절하는 변수, 인스펙터에서 설정 가능
  • curMovementInput : 입력값을 저장하는 변수(이동 입력을 저장하는 역할), Vector2로 x, y 움직임을 저장
  • move() 메서드를 만들어 Update에서 호출

Player 오브젝트를 드래그 하여 넣어주고 OnMove를 잘 넣어준 다음

컴포넌트에 있는 MoveSpeed를 설정해주면 끝.

 

 

Look

public class PlayerController : MonoBehaviour
{
    [Header("Look")]
    public Transform cameraContainer;
    public float minXLook; // 회전범위, x 최소값
    public float maxXLook; // 회전범위, x 최대값
    private float camCurXRot; // 마우스의 델타값을 받아오는것, X축 회전값
    public float lookSensitivity; // 마우스 감도
    private Vector2 mouseDelta; // 마우스 이동값, 입력에서 받아와야함

    private void LateUpdate()
    {
        CameraLook();
    }

    void CameraLook()
    {
        // 마우스 y값(위아래 움직임)을 lookSensitivity만큼 곱해서 현재x값에 더함
        // 위로 이동시 camCurXRot 증가 > 카메라 아래쪽을 바라봄
        camCurXRot += mouseDelta.y * lookSensitivity;
        // 카메라 상하 회전 제한
        camCurXRot = Mathf.Clamp(camCurXRot, minXLook, maxXLook);
        // y,z축은 0으로 고정해줌으로써 x축만 회전 (상하움직임)
        cameraContainer.localEulerAngles = new Vector3(-camCurXRot, 0, 0);

        //y축 회전(좌우)적용, 마우스를 움직이면 캐릭터 전체가 회전함
        transform.eulerAngles += new Vector3(0, mouseDelta.x * lookSensitivity, 0);
    }
}
  • cameraContainer : 카메라 부착 오브젝트
  • camCurXRot : 카메라의 x축 회전값
  • lookSensitivity : 마우스 감도

최소, 최대값은 Inspector에서 설정