유니티

InputManager

코다람쥐 2022. 2. 3. 14:33

https://codaitsme.tistory.com/82

 

Managers 클래스와 싱글톤(Singleton) 패턴

1. 정의 싱글톤 패턴은 어떤 객체의 인스턴스가 단 1개만 존재할 때 사용하는 패턴이다. static을 사용하며 구현하면 된다. 특징으로는 유일성이 보장된다. 2. 매니저 클래스 유니티에서 게임을 관

codaitsme.tistory.com

 

1. InputManager 클래스

예전엔 Managers클래스를 설계하였는데 역할에 따라 다양한 매니저클래스들을 정의할 수 있다.

이번에 알아볼 매니저 클래스는 InputManager로 키보드나 마우스와 같은 입력에 관한 관리를 해주는 클래스이다.

public class InputManager
{
    public Action KeyAction = null; // Action은 일종의 델리게이트다.

    public void OnUpdate()
    {
        if (Input.anyKey == false) // 아무런 키도 입력되지 않으면 return을 한다.
            return;

        if (KeyAction != null)
            KeyAction.Invoke();
            // InputManager.KeyAction을 구독한 모든 객체들에게 메시지를 전달하는 방식으로 구현하였다.
    }
}

 

그리고 매니저 클래스에는 기존의 코드에 2줄의 코드를 넣어주어서 매니저 클래스에서만 InputManger에 접근이 가능하도록 하였다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Managers : MonoBehaviour
{
    static Managers s_instance;
    static Managers Instance { get { Init(); return s_instance;} }

    InputManager _input = new InputManager(); // 새롭게 추가함
    public static InputManager Input { get { return Instance._input; } } // 새롭게 추가함
    
    void Start()
    {
        Init();
    }
    void Update()
    {
        _input.OnUpdate();
    }
    static void Init()
    {
        if (s_instance == null)
        {
            GameObject go = GameObject.Find("Manager");
            if (go == null)
            {
                go = new GameObject { name = "Manager" };
                go.AddComponent<Managers>();
            }

            DontDestroyOnLoad(go);
            s_instance = go.GetComponent<Managers>();
        }
    }
}

 

사용방법

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    float _speed;
    void Start()
    {
        Managers.Input.KeyAction -= OnKeyboard; // 기존에 구독한걸 끊음
        Managers.Input.KeyAction += OnKeyboard; // 다시 구독
    }

    float value = 0.05f;

    void OnKeyboard() // 플레이어 조작함수
    {

        if (Input.GetKey(KeyCode.W))
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), value);
            transform.position += Vector3.forward * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.S))
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), value);
            transform.position += Vector3.back * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.D))
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), value);
            transform.position += Vector3.right * Time.deltaTime * _speed;
        }
        if (Input.GetKey(KeyCode.A))
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), value);
            transform.position += Vector3.left * Time.deltaTime * _speed;
        }
    }
}

OnKeyboard()함수는 키보드를 통해 플레이어를 조작하는 함수이므로 자세하게 분석할 필요는 없다.

중요한건 Start()안에 있는 내용이다.

C#의 문법인 이벤트(Event)를 사용하여 InputManager.KeyAction을 구독하였다.

그리고 프로그래머의 실수로 구독을 2번하는 경우도 생기는데 이것을 방지하기 위해 새롭게 구독하면 기존의 구독을 끊고 다시 구독하게 구현되어있다.

 

이렇게 구현하면 OnKeyboard의 내용을 Update문에서 직접 구현하였을 때 보다 성능적인 면에서 우수하다.