전체 코드

1. InputManager란?

InputManager는 Unity에서 키 입력을 효율적으로 관리하기 위해 사용하는 시스템입니다.

📌 InputManager의 필요성

  • 성능 향상: Update() 함수 내에서 직접 키 입력을 관리하면, 매 프레임마다 불필요한 입력 체크가 이루어질 수 있음 → InputManager를 사용하면 최적화 가능.
  • 유지보수 용이: 입력 처리 로직을 분리하여 PlayerController와 같은 스크립트에서 독립적으로 관리 가능.
  • 확장성 증가: 입력 로직을 다른 스크립트에서도 재사용 가능하게 만들어 코드 중복을 방지.

2. InputManager 코드 분석

📜 InputManager.cs

using System;
using UnityEngine;

public class InputManager
{
    public Action KeyAction = null; // 입력 이벤트를 저장하는 델리게이트

    public void OnUpdate()
    {
        if (!Input.anyKey) // 어떤 키 입력도 없으면 함수 종료
            return;

        KeyAction?.Invoke(); // KeyAction이 비어있지 않다면 모든 등록된 함수 실행
    }
}

📌 코드 분석

  1. Action KeyAction
    • 델리게이트 Action을 사용해, 키 입력 이벤트를 등록할 수 있도록 만듦.
    • KeyAction에 여러 개의 입력 처리 함수를 추가할 수 있음.
  2. OnUpdate()
    • Input.anyKey를 통해 아무 키도 눌리지 않으면 함수 실행 안 함.
    • KeyAction?.Invoke()를 호출해, KeyAction에 등록된 모든 함수 실행.

3. Managers.cs (싱글톤 + 입력 시스템 통합)

📜 Managers.cs

using UnityEngine;

public class Managers : MonoBehaviour
{
    static Managers s_instance; // 싱글톤 인스턴스
    static Managers Instance { get { Init(); return s_instance; } }

    InputManager _input = new InputManager(); // InputManager 인스턴스 생성
    public static InputManager Input { get { return Instance._input; } }

    void Start()
    {
        Init();
    }

    void Update()
    {
        _input.OnUpdate(); // 매 프레임 InputManager의 OnUpdate() 실행
    }

    static void Init()
    {
        if (s_instance == null)
        {
            GameObject obj = GameObject.Find("@Managers");
            if (obj == null)
            {
                obj = new GameObject { name = "@Managers" };
                obj.AddComponent<Managers>();
            }

            DontDestroyOnLoad(obj); // 씬이 변경되어도 Managers 오브젝트 유지
            s_instance = obj.GetComponent<Managers>();
        }
    }
}

📌 코드 분석

  1. 싱글톤 패턴 적용

    • static Managers s_instance: 게임 내에서 단 하나의 Managers 인스턴스만 유지하도록 보장.
    • Instance 프로퍼티를 통해 언제든 Managers 인스턴스에 접근 가능.
  2. InputManager 인스턴스 통합

    • _input 변수를 통해 InputManager 객체를 생성 및 관리.
    • public static InputManager Input을 사용해 전역 접근 가능하도록 설정.
  3. 씬 변경 시에도 유지

    • DontDestroyOnLoad(obj);를 호출하여, Managers 오브젝트가 씬이 변경될 때 삭제되지 않도록 설정.
  4. Update()에서 InputManager 호출

    • 매 프레임 OnUpdate() 실행 → 키 입력이 있는지 확인.

4. PlayerController.cs (입력 처리)

📜 PlayerController.cs

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    float _speed = 10.0f; // 이동 속도

    void Start()
    {
        Managers.Input.KeyAction -= OnKeyboard; // 중복 등록 방지
        Managers.Input.KeyAction += OnKeyboard; // 키 입력 함수 등록
    }

    void OnKeyboard()
    {
        if (Input.GetKey(KeyCode.W)) // W키를 누르면 전진
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), 0.2f);
            transform.position += Vector3.forward * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.S)) // S키를 누르면 후진
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f);
            transform.position += Vector3.back * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.A)) // A키를 누르면 왼쪽으로 이동
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f);
            transform.position += Vector3.left * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.D)) // D키를 누르면 오른쪽으로 이동
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);
            transform.position += Vector3.right * Time.deltaTime * _speed;
        }
    }
}

📌 코드 분석

  1. 키 입력 처리 등록

    • Managers.Input.KeyAction -= OnKeyboard;
    • Managers.Input.KeyAction += OnKeyboard;
    • 중복 등록을 방지하기 위해 기존 등록을 먼저 제거한 후 다시 추가.
  2. 키 입력 감지 및 처리

    • OnKeyboard() 함수에서 Input.GetKey()를 사용하여 W, A, S, D 키 입력을 감지.
    • Quaternion.Slerp()을 사용하여 부드럽게 회전.
    • transform.position을 변경하여 캐릭터 이동.

5. 전체 동작 흐름

[사용자 입력] → InputManager 감지 → KeyAction Invoke → PlayerController의 OnKeyboard() 호출 → 캐릭터 이동/회전

📌 정리

  1. Managers.cs

    • Singleton 패턴으로 전역에서 InputManager를 관리.
    • Update()에서 InputManager의 OnUpdate()를 매 프레임 호출.
  2. InputManager.cs

    • 리스너 패턴을 사용하여 입력 이벤트를 등록하고 실행.
    • OnUpdate()에서 키 입력을 감지하고 등록된 KeyAction을 실행.
  3. PlayerController.cs

    • Start()에서 KeyActionOnKeyboard() 등록.
    • OnKeyboard()에서 W, A, S, D 키 입력을 감지하여 이동 및 회전 처리.

6. InputManager의 장점

장점설명
성능 향상매 프레임마다 불필요한 입력 체크를 최소화
유지보수 용이입력 로직을 분리하여 PlayerController의 코드가 간결해짐
확장성 증가키 입력을 다른 스크립트에서도 쉽게 등록하고 관리 가능
싱글톤 패턴 적용게임 전역에서 Managers.Input을 통해 언제든 입력 관리 가능

profile
李家네_공부방

0개의 댓글