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

게임을 제작할 때, UI, 입력, 사운드 등 여러 요소를 관리하기 위해 사용된다.

기본이 되는 Manager에 UI Manager, Input Manager 등 세부 관리기능을 붙여준다고 생각하면 된다.

게임에서 사용되는 Manager는 전역으로 한 개만 선언되어 사용한다. 따라서 Singleton 패턴을 사용한다.

 

public class Managers : MonoBehaviour
{
    static Managers s_instance
    static Managers Instance { get { Init(); return s_instance; } }
    
    public static _input = new InputManager();
    public static InputManager Input { get { Init(); return Instance._input; } }
    
    void Start()
    {
    	Init()
    }
    
    void Update()
    {
    
    }
    
    static void Init()
    {
    	if (s_instance == null)
        {
    		GameObject go = GameObject.Find("@Managers");
        	if (go == null)
        	{
        		go = new GameObject { name = "@Managers" };
            	go.AddComponent<Managers>();
        	}
        	DontDestroyOnLoad(go);
        	s_instance = go.GetComponent<Managers>();
    	}
    }
}

 

 

Managers 클래스의 전역변수인 s_instance를 선언해준다. 위 코드는 InputManager를 Manager에 붙여준 코드이다.

메인 코드에서는 Managers.Input 을 통해 입력 제어를 할 수 있다.

 

Init 함수에서는 전역변수가 존재하지 않거나, @Managers 라는 Manager를 관리하는 게임 오브젝트가 존재하지 않을 때 새로운 @Managers 라는 매니저 게임 오브젝트를 생성하여 Managers.cs 스크립트를 Component로 붙여준다.

'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 - InputManager  (1) 2024.01.08

+ Recent posts