728x90

저는 심플한 게임을 만들어 보려고 합니다. 이번에 필요한 것은 키 입력 시 캐릭터를 이동하는 겁니다.

먼저 Input Action은 초보이므로 제공하는걸 사용합니다.

그리고 Player Input 컴포넌트의 Behavior는 쉬운 Send Messages (기본값) 와 Invoke Unity Events (입문자 권장) 를 사용해 보려 합니다.

 

처음의 생각은 아주 순진하게도 특정키를 입력하면 이벤트 트리거 같은 것이 캐치하는 걸 생각 했습니다.

하지만 이젠 권장하지 않는다고 해서 New Input System 이라는 먼 길을 돌아왔습니다.

( 이전글 [unity6] New Input System - 01. 기본 가이드 또는 가이드 영상 참조)

 

사용된 캐릭터 오브젝트에 적용된 C# 스크립트 파일은 Player.cs 입니다.

 

1. 캐릭터 오브젝트에 Player Input 컴포넌트 추가 (Actions 에는 이미 제공되어 있는 Input Action 파일이 자동으로 들어감)

Actions에 파일을 더블 클릭하면 Input Action이 작성된 것을 확인할 수 있습니다.

여기에 작성된 정보는 "Player는 이런 액션을 사용할 수 있는데 각 액션에는 어떤 입력을 바인딩 한다." 라고 정의해 둔 것 입니다.

위 이미지의 노란색 박스가 Behavior를 설정하는 부분입니다.

 

1-1. Behavior를 Send Messages 사용시

액션이 Move 라고 정의되어 있다면 C# 코드의 OnMove 함수를 호출하게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using UnityEngine;
using UnityEngine.InputSystem;
 
public class Player : MonoBehaviour
{
 
    private Vector2 inputDirection; // 입력받은 방향을 저장할 변수
 
    /// <summary>
    /// Action Input > Behavior > Send Message 사용시
    /// : 이동 입력을 받았을 때 호출되는 함수 (이름이 정해져 있음: On + Action이름)
    /// </summary>
    /// <param name="value"></param>
    void OnMove(InputValue value)
    {
        Logger.Log("Call OnMove()", LogLevel.Debug);
        // 키 입력 방향 세팅
        inputDirection = value.Get<Vector2>();
        MoveAction(inputDirection);
    }
 
    /// <summary>
    /// Move 액션에 대한 상세
    /// </summary>
    /// <param name="inputDirection"></param>
    void MoveAction(Vector2 inputDirection)
    {
        Logger.Log($"현재 입력 방향: {inputDirection}", LogLevel.Debug);
 
        // 타일만큼 이동시
        // 키를 누르는 순간(값이 0이 아닐 때)에만 이동
        if (inputDirection != Vector2.zero)
        {
            // 이동거리 (타일사이즈)
            float tileSize = 1f;
 
            // 1. 대각선 입력을 방지하고 상하좌우 중 가장 큰 값만 취함 (선택 사항)
            // WASD를 같이 눌러 (0.7, 0.7)이 되는 것을 방지합니다.
            if (Mathf.Abs(inputDirection.x) > Mathf.Abs(inputDirection.y))
                inputDirection = new Vector2(Mathf.Abs(inputDirection.x) / inputDirection.x, 0);
            else
                inputDirection = new Vector2(0, Mathf.Abs(inputDirection.y) / inputDirection.y);
 
            // 2. 현재 위치 + (방향 * 타일 사이즈)
            Vector3 targetPosition = transform.position + new Vector3(inputDirection.x * tileSize, inputDirection.y * tileSize, 0f);
 
            // 3. 위치 업데이트
            transform.position = targetPosition;
 
            Logger.Log($"이동 방향: {inputDirection}, 목표 좌표: {targetPosition}", LogLevel.Debug);
        }
    }
}
 
cs

코드를 간단히 리뷰하면 아래와 같습니다.

1-1-1. 방향키 입력시 Move에 정의된 Input에 의해 OnMove를 호출

1-1-2. 매개변수에서 Vector2 값을 가져와 inputDirection에 방향에 해당되는 값을 적용

1-1-3. MoveAction을 호출하여 실제 캐릭터의 포지션을 이동

※ Logger.Log()는 Debug.Log()로 대체해도 됩니다.

 

1-2. Behavior를 Invoke Unity Events 사용시

먼저 사용할 코드를 아래와 같이 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
 
public class Player : MonoBehaviour
{
 
    ...
 
 
    // Action Input > Behavior > Invoke Unity Events 사용시
    public void OnMoveInvokeEvent(InputAction.CallbackContext context)
    {
        // 1. 오직 '완전히 눌렸을 때(Performed)'만 로직을 실행하도록 제한
        if (!context.performed) return;
 
        Logger.Log("Call OnMoveInvokeEvent()", LogLevel.Debug);
 
        // 키 입력 방향 세팅
        inputDirection = context.ReadValue<Vector2>();   // value.Get<Vector2>();
        MoveAction(inputDirection);
 
    }
 
    ...
 
}
 
cs

해당 코드에서 주의할 점은 13번 라인입니다. 해당 코드가 없는 경우 키를 누를때, 뗄때 총 2번 이벤트가 발생되어 의도한 것 보다 2배 이동합니다.

 

이제 작성한 코드를 액션에 연결 하겠습니다.

1-2-1. Player Input 컨포넌트에서 Events 항목에서 사용할 Action Map을 열기 (여기서는 Player)

 

 

1-2-2. Events > Player > Move 액션에 추가 (추가 전은 List is Empty) > 액션에 대한 C# 코드를 가진 오브젝트를 넣기 (여기서는 자기 자신인 캐릭터 오브젝트) > No function > C# 코드 > 코딩한 액션 함수 (함수명은 개발자가 임의로 지정해도 됨)

 

 

 

이렇게 하면 원하는 바와 같이 방향키 입력 시 지정한 만큼 캐릭터가 이동됩니다.

 

2. 키보드를 누르고 있는 만큼 이동

위 예시는 키를 누르고 있어서 1번 지정된 만큼만 이동됩니다.

그렇다면 누르고 있는 만큼 거리를 계속해서 이동하는 코드의 예시입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
...
 
public class Player : MonoBehaviour
{
 
    private Vector2 inputDirection; // 입력받은 방향을 저장할 변수
 
    private float moveSpeed = 1f;
 
    // Update is called once per frame
    void Update()
    {
        /**
         * 부드러운 이동시 사용할 셈플
         */
        // 1. 방향 * 속도 * 프레임보정(deltaTime)을 계산합니다.
        // 현재 2D 기준(x, y)으로 작성하셨으므로 그대로 유지합니다.
        Vector3 moveAmount = new Vector3(inputDirection.x, inputDirection.y, 0f) * moveSpeed * Time.deltaTime;
 
        // 2. 최종 위치 이동
        transform.position += moveAmount;
    }
 
    /// <summary>
    /// Action Input > Behavior > Send Message 사용시
    /// : 이동 입력을 받았을 때 호출되는 함수 (이름이 정해져 있음: On + Action이름)
    /// </summary>
    /// <param name="value"></param>
    void OnMove(InputValue value)
    {
        Logger.Log("Call OnMove()", LogLevel.Debug);
        // 키 입력 방향 세팅
        inputDirection = value.Get<Vector2>();
    }
 
    // Action Input > Behavior > Invoke Unity Events 사용시
    public void OnMoveInvokeEvent(InputAction.CallbackContext context)
    {
        // 1. 오직 '완전히 눌렸을 때(Performed)'만 로직을 실행하도록 제한
        //if (!context.performed) return;
 
        Logger.Log("Call OnMoveInvokeEvent()", LogLevel.Debug);
 
        // 키 입력 방향 세팅
        inputDirection = context.ReadValue<Vector2>();   // value.Get<Vector2>();
 
    }
}
 
cs

간단히 리뷰하면 아래와 같습니다.

2-1. Update 매소드는 프레임 마다 실행됩니다.

2-2. 각 프레임마다 실행되므로 누르고 있는 동안 계속해서 이동합니다.

2-3. 실행되는 기기마다 성능이 달라서 이동 값 Vector3 * moveSpeed * Time.deltaTime 를 합니다.

2-4. 40번 라인을 주석처리 하지 않으면 키 입력이 종료될 때를 감지하지 못해서 계속해서 이동합니다.

 

오늘은 여기까지... OTL

 

 

 

### 목차 ###

[unity6] New Input System - 01. 기본 가이드

[unity6] New Input System - 02. 단순 구현하기

 

728x90
반응형

+ Recent posts