InputManager는 유니티에서 입력을 제어하는 Manager이다. 전역변수로 선언된 Manager의 Update 함수에 주기적으로 입력을 감지하는 코드를 붙여준다. 입력이 감지되면 플레이어를 제어하는 PlayerController에 OnKeyBoard 라는 함수가 실행되도록 Managers의 InputManager 안의 KeyAction 델리게이트에 넣어준다.
Managers.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Managers : MonoBehaviour
{
static Managers s_instance;
static Managers Instance { get { return s_instance; } }
InputManager _input = new InputManager();
public static InputManager Input { get { Init(); return Instance._input; } }
// Start is called before the first frame update
void Start()
{
Init();
}
// Update is called once per frame
void Update()
{
// InputManager의 OnUpdate 함수를 계속 실행하여 KeyAction이 존재한다면
// PlayerController에서 연결시켜준 OnKeyBoard 함수를 Update함수에서 돌려준다.
_input.OnUpdate();
}
static void Init()
{
if (s_instance == null) // 전역변수로 선언된 Manager가 있는지
{
GameObject go = GameObject.Find("@Managers"); // Manager 코드를 담을 객체를 찾는다
if (go == null) // 존재하지 않을 시, Manager 스크립트를 붙인 오브젝트를 만든다.
{
go = new GameObject { name = "@Managers" };
go.AddComponent<Managers>();
}
DontDestroyOnLoad(go); // 실행되는 동안 삭제되지 않는다.
s_instance = go.GetComponent<Managers>();
// 생성한 게임 오브젝트의 컴포넌트로 붙은 Managers 를 가져온다.
}
}
}
InputManager.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InputManager
{
public Action KeyAction = null; // 델리게이트를 선언하여 함수를 받는다.
public void OnUpdate() // Managers 의 Update 함수에서 실행 될 함수를 선언
{
if (Input.anyKey == false)
return;
// PlayerController에서 Start가 실행되고, KeyAction 델리게이트에
// OnKeyBoard 함수가 들어가게 되고, 아래 코드가 실행된다.
if (KeyAction != null)
KeyAction.Invoke(); // 할당된 OnKeyBoard 함수가 실행
}
}
PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
float _speed = 10;
void Start()
{
// InputManager에 입력 신호가 발생했을 때 실행될 함수를 붙인다.
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.A))
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f);
transform.position += Vector3.left * 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.D))
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);
transform.position += Vector3.right * Time.deltaTime * _speed;
}
}
}
PlayerController의 OnKeyBoard 함수를 이용하여 WASD 로 플레이어를 이동할 수 있다.
transform.rotation을 통해 오브젝트의 각도를 조절한다. 이때, Quaternion.Slerp 함수를 이용하여 오브젝트의 Rotate 를 더 자연스럽게 연결시켜서 변경한다.
Quaternion.Slerp(시작 Rotate, 최종 Rotate, 변경정도)
transform.position은 오브젝트의 위치를 변경할 수 있다. 위 함수에서는 Vector3의 forward, left, right, back 의 단위벡터를 이용하여 이동할 방향을 주었고, 속도 변수인 _speed를 이용해 속도를 설정할 수 있었다. 또한 deltaTime을 곱해주는 이유는 디바이스마다 호출되는 프레임의 수가 다르기 때문에 동일하게 움직이기 위해 곱해주었다.
'UNITY' 카테고리의 다른 글
UNITY - UI 자동화(1) - 인벤토리 구현 (0) | 2024.01.11 |
---|---|
UNITY - UIManager (2) | 2024.01.11 |
UNITY - Camera - 3인칭 시점(2) (4) | 2024.01.08 |
UNITY - Camera - 3인칭 시점(1) (3) | 2024.01.08 |
UNITY - Manager (1) | 2024.01.03 |