[Unity]이벤트(Event)로 키 입력 관리하기
본 포스팅은 아래 링크의 강의를 듣고 정리한 것입니다.
https://www.inflearn.com/course/mmorpg-%EC%9C%A0%EB%8B%88%ED%8B%B0
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진 - 인프런 | 강의
유니티 엔진 사용법 및 제공하는 기능들에 대해 알아보고, 그것을 효율적으로 관리하는 방법을 배우는 강의입니다., - 강의 소개 | 인프런...
www.inflearn.com
📕이벤트(Event)로 키 입력 관리하기
유니티에서 키 입력을 받으려면 Update() 함수에서 Input.Getkey()를 호출해 주면 된다. 이렇게만 해도 게임에 쓰일 키 입력 시스템을 구현하는 데에는 지장이 없지만 이벤트를 사용하면 더욱 효과적으로 키 입력 시스템을 만들 수 있다.
먼저 이벤트를 사용하지 않고 Update() 함수에서 직접 Input.Getkey()를 호출하는 코드를 살펴보자.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
float _speed = 10f;
void Update()
{
if (Input.GetKey(KeyCode.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))
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f);
transform.position += Vector3.back * Time.deltaTime * _speed;
}
if (Input.GetKey(KeyCode.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))
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);
transform.position += Vector3.right * Time.deltaTime * _speed;
}
}
}
'WSAD' 키로 캐릭터를 이동시키는 코드이다. 키 입력을 감지해야 하기 때문에 키를 입력하지 않을 때도 계속 Update() 함수 안의 코드를 호출해야 한다. 이 경우 나중에 캐릭터를 추가하거나 인터페이스와 관련된 조작키를 추가할 시 성능 저하가 발생하게 된다. 키 입력을 받기 위해 관련된 모든 스크립트에서 Update() 함수를 호출해야 하기 때문이다.
이를 해결하려면 키 입력 신호를 전달할 이벤트에 키 입력을 처리할 메서드(이벤트 핸들러)를 등록해 키 입력 이벤트가 발생했을 시에만 해당 메서드가 동작하도록 하면 된다.
🔗Script: InputManager
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InputManager
{
public Action KeyAction = null;
public void OnUpdate()
{
if (Input.anyKey == false)
return;
if (KeyAction != null)
KeyAction.Invoke();
}
}
InputManager 클래스를 만들어 KeyAction 이벤트 선언했다. 컴포넌트 용도가 아니기 때문에 MonoBehaviour는 상속받지 않았다. OnUpdate() 함수는 매니저 클래스들을 관리하는 Managers 클래스의 Update() 함수에서 호출되며, 키 입력이 들어올 시 KeyAction.Invoke()를 통해 등록된 이벤트 핸들러를 실행하는 역할을 한다.
🔗Script: PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
float _speed = 10f;
void Start()
{
Managers.Input.KeyAction -= OnKeyboard;
Managers.Input.KeyAction += OnKeyboard;
}
void OnKeyboard()
{
if (Input.GetKey(KeyCode.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))
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f);
transform.position += Vector3.back * Time.deltaTime * _speed;
}
if (Input.GetKey(KeyCode.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))
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);
transform.position += Vector3.right * Time.deltaTime * _speed;
}
}
}
이동 코드는 OnKeyboard() 메서드로 만든 뒤 KeyAction 이벤트에 등록했다. 이렇게 하면 캐릭터가 늘어나더라도 InputManager에서만 키 입력을 확인하기 때문에 효율적이다.