유니티
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문에서 직접 구현하였을 때 보다 성능적인 면에서 우수하다.