unity/유니티 초보

Unity - new Input System 사용법

rimugiri 2024. 1. 23. 23:59
728x90

서론

기존에 캐릭터의 움직임을 제어할 경우 유니티에 있던 Input Manger을 사용해 왔을것이다.
그렇지만 기존의 InputSystem보다 Observer 패턴을 더 잘 활용할 수 있고 코드를 더 깔끔하게 관리할 수 있으며 여기에서는 소개하지 않지만 Scheme설정을 통해 PC, Moblie같은 특정 타겟마다 Input System을 설정할 수 있는 장점을 가지고 있는 새로운 Input System을 알게되어 소개한다.

사용법 - 2DGame

1. InputSystem package 설치

2. PlayerInput component 추가 및 InputAction 추가

  • project창 -> 마우스왼쪽클릭 -> create -> 맨밑쪽 InputAction 생성 -> 더블클릭후 이름 정의

Action Type에는 Value와 Button은 둘다 처음과 끝에서 한번씩 호출되는 반면 pass through는 연속적으로 호출이 이루어진다

Control Type의 경우 키가 입력되었을 경우 그 값을 어떤 타입으로 다루고 싶은지 선택하면 된다 여기서는 Move와 Look 모두 캐릭터의 이동방향 마우스의 위치를 얻어오기 위해 Vector2로 선택하였다.

움직임을 위해 2번 Add

Mode경우에는 Digital Normalized로 하면 대각선으로 이동할 경우 더 많이 움직이는 것을 사전에 방지 할 수 있다

나머지는 각각 해당하는 키를 설정해 두면 Move는 완성되었다

마우스의 위치를 플레이어가 바라보도록 설정하기 위해 Mouse -> Position을 Path로 설정하였다

Compostie Type

  • Player오브젝트에 PlayerInput component추가

Actions에 기존에 만들었던 InputAction을 등록한다

여기서 Behavior 경우 Send Messages로 설정하면 InputAction으로 등록한 각각의 Action에 On이 붙어 OnMove(), OnLook 함수를 사용하여 키나 마우스의 값을 받아 올 수 있다.

BroadCastMessages는 이 오브젝트의 자식오브젝트에서도 이 함수 실행이 가능해 진다.

3. 스크립트 추가

Player 구성
캐릭터를 제어하기 위해 3개의 스크립트를 추가해 준다

  • PlayerInputController
    // 값을 전달해 주며 이벤트를 호출 하는 클래스이다
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerInputController : TopDownCharacterController
{
    // 눌렀을경우 한번 뗐을 때 한번이 호출된다
    public void OnMove(InputValue value)
    {
        Vector2 direction = value.Get<Vector2>();
        CallMoveEvent(direction);
    }
    // 마우스가 움직일 때마다 호출된다
    public void OnLook(InputValue value)
    {
        // 설정해 두었던 mouse의 위치를 받아온다
        // 이때 이 위치를 Screen 위치므로 주의해야 한다
        Vector2 mousePosition = value.Get<Vector2>();
        mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
        Vector2 direction = mousePosition - (Vector2)transform.position;
        CallLookEvent(direction);
    }
}
  • TopDownCharacterController
    // 이벤트를 담고 있으며 이벤트를 감지하고 실행되는 클래스이다
using System;
using UnityEngine;

public class TopDownCharacterController : MonoBehaviour
{
    // 다른 곳에서 evnt를 직접 Invoke 하는것을 막아준다
    public event Action<Vector2> OnMoveEvent;
    public event Action<Vector2> OnLookEvent;

    public void CallMoveEvent(Vector2 direction)
    {
        OnMoveEvent?.Invoke(direction);
    }
    public void CallLookEvent(Vector2 direction)
    {
        OnLookEvent?.Invoke(direction);
    }
}
  • TopDownMovement
    // 캐릭터의 움직임을 담당한다
using System;
using UnityEngine;

public class TopDownMovement : MonoBehaviour
{
    TopDownCharacterController _characterController;
    Rigidbody2D _rigidbody;
    SpriteRenderer _characterSprite;
    Vector2 _direction;
    [SerializeField] [Range(10,1000)] float _speed;
    void Awake()
    {
        _characterController = gameObject.GetComponent<TopDownCharacterController>();
        _rigidbody = gameObject.GetComponent<Rigidbody2D>();
        _characterSprite = gameObject.GetComponentInChildren<SpriteRenderer>();
    }
    private void Start()
    {
        // 이벤트 등록
        _characterController.OnMoveEvent += Move;
        _characterController.OnLookEvent += Look;
    }
    void FixedUpdate()
    {
        ApplayMovement();
    }
    private void Look(Vector2 direction)
    {
        // 2D Sprite를 뒤집어 마우스 방향을 바라보게 만든다
        _characterSprite.flipX = (direction.x < 0);
    }
    void Move(Vector2 direction)
    {
        // 이동 방향 등록
        _direction = direction;
    }
    void ApplayMovement()
    {
        // rigidbody를 이용한 캐릭터 이동
        _rigidbody.velocity = _direction * _speed;
    }
}

4. 실행 결과

0

728x90