[Unity UI] 유니티로 인게임 키 입력(단축키) 설정 기능 만들기

목차

  1. 키 입력 설정 기능이란?
  2. 스크립트(코드) 및 설명
  3. 결과

1. 키 입력 설정 기능이란?

다들 게임을 하다보면 디폴트로 박혀있는 키 입력들이 있죠?

로스트아크 키입력 단축키

제가 즐겨하는 로스트아크의 설정에 단축키 기능인데요.

프로젝트로 게임개발을 하는데 단축키 설정기능을 구현을 해야해서 로아를 키고 어떤 기능이 있나 이렇게 켜보았습니다.

 

로직을 보니 저 키입력을 한번 누르고 바꿀 키로 다시 눌러주면 해당 기능이 바꾼 키로 작동하도록 되어있더라구요.

그래서 그런 기능이 있나 구글링 하면서 찾아보고 구현에 성공해서 공유해드리고자 합니다.


2. 스크립트(코드) 및 설명

KeyManger.cs

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

public enum KeyInput {
    UP, //1
    DOWN, //2
    LEFT, //3
    RIGHT, //4
    JUMP, //5
    Item1,  //7
    Item2, //8
    Item3, //9
    SoundWave, //10
    sDown1, //11
    sDown2, //12
    sDown3, //13
    sDown4, //14
    TouchNPC, //15
    KEYCOUNT } //키 카운트를 재기위해 keycount설정

public static class KeySetting { 
    public static Dictionary<KeyInput, KeyCode> keys = new Dictionary<KeyInput, KeyCode>(); 
}
public class KeyManager : MonoBehaviour
{
    //key Code EnumType
    KeyCode[] defaultKeys = new KeyCode[] {
        KeyCode.W, //UP
        KeyCode.S, //Down
        KeyCode.A,  //Left
        KeyCode.D,  //Right
        KeyCode.Space, //Jump
        KeyCode.Alpha1, //Item1
        KeyCode.Alpha2, //Item2
        KeyCode.Alpha3, //Item3
        KeyCode.F, //SoundWave
        KeyCode.F1, //sDown1
        KeyCode.F2, //sDown2
        KeyCode.F3, //sDown3
        KeyCode.F4, //sDown3
        KeyCode.G, //NPC 상호작용 대화
    };
    void Awake()
    {
        KeySetting.keys.Clear(); //Key SetClear
        for(int i=0; i < (int)KeyInput.KEYCOUNT; i++) //Key Change
        {
            KeySetting.keys.Add((KeyInput)i,defaultKeys[i]);
        }
    }

    // Update is called once per frame
    void Update()
    {
        TestInput();
    }
    private void OnGUI()
    {
        Event keyEvent = Event.current;
        if (keyEvent.isKey)
        {
            KeySetting.keys[(KeyInput)key] = keyEvent.keyCode;
            key = -1;
        }
    }
    int key = -1;
    public void ChangeKey(int num) //키 값 바꾸는 함수
    {
        key = num;
    }

    private void TestInput() {
        //UP,
        //DOWN,
        //LEFT,
        //RIGHT,
        //JUMP,
        //Run,
        //Inventory,
        //Item1,
        //SoundWave
        //sDown1
        //sDown2
        //sDown3
        //sDown3
        //
        //
        if (Input.GetKey(KeySetting.keys[KeyInput.UP])) //UP
        {
            //Debug.Log("Up");
        }
        if (Input.GetKey(KeySetting.keys[KeyInput.DOWN])) //Down
        {
           // Debug.Log("DOWN");
        }
        if (Input.GetKey(KeySetting.keys[KeyInput.LEFT])) //Left
        {
           // Debug.Log("LEFT");
        }
        if (Input.GetKey(KeySetting.keys[KeyInput.RIGHT])) //Right
        {
           // Debug.Log("RIGHT");
        }
        if (Input.GetKey(KeySetting.keys[KeyInput.JUMP])) //Jump
        {
           // Debug.Log("JUMP");
        }
        if (Input.GetKeyDown(KeySetting.keys[KeyInput.Item1])) //item1
        {
            ItemInventory.instance.selectedItemIndex = 0; // 첫 번째 아이템 슬롯 선택
            ItemInventory.instance.UseSelectedItem(); // 선택된 아이템 사용
        }
        if (Input.GetKeyDown(KeySetting.keys[KeyInput.Item2])) //Item2
        {
            ItemInventory.instance.selectedItemIndex = 1; // 첫 번째 아이템 슬롯 선택
            ItemInventory.instance.UseSelectedItem(); // 선택된 아이템 사용
        }
        if (Input.GetKeyDown(KeySetting.keys[KeyInput.Item3])) //Item3
        {
            ItemInventory.instance.selectedItemIndex = 2; // 첫 번째 아이템 슬롯 선택
            ItemInventory.instance.UseSelectedItem(); // 선택된 아이템 사용
        }
        if (Input.GetKey(KeySetting.keys[KeyInput.TouchNPC])) //TouchNPC
        {
            Debug.Log("NPC G Input");
        }
    }
}

 

제가 프로젝트에 구현한 코드입니다.

위에서 부터 차례로 보겠습니다.

 

public으로 KeyInput이라는 enum 으로 기능의 이름들을 적어줍니다. 마지막에는 키의 갯수를 알기위한 KEYCOUNT를 넣어주었습니다.

 

그 후 KeySetting이라는 클래스를 만들어 딕셔너리로 아까만든 KeyInput을 키값으로두고 유니티안에 구현되어있는 KeyCode를 Value로 해줍니다.

 

이제 KeyManager클래스에서 KeyCode형으로 디폴트 키값들을 배열로 각각 설정해줍니다. 이때 중요한 것은 위 enum과 순서가 동일해야 합니다.

이후 Awake에서 키값들을 클리어시켜서 혹시모를 오류를 확실히 방지하고 enum에 해당하는 기본키들을 할당해줍니다.

 

Update함수에 TestInput은 입력을 처리하는 함수로 매 프레임마다 입력을 감지하도록 넣어주었습니다.

 

OnGUI는 이벤트를 처리하는 함수로 키입력을 변경하기 위해 넣어주었습니다.

ChageKey함수도 키 입력 변경을 위한 함수입니다.

이 함수를 버튼에 적용시켜주면됩니다. 이후에 버튼의 텍스트도 이용해서 UI로 시각적으로 보이도록 해줄겁니다.

 

TestInput함수에서는 if문으로 도배를 하여 해당 키입력을 받으면 실행할 기능들을 구현해주면 됩니다.

근데 보시면 GetKey와 GetKeyDown 2가지 방식이 있습니다.

GetKey는 한번입력받으면 프레임단위로 실행시키고

GetKeyDown은 한번 입력받으면 한번만 실행시켜줍니다.

이렇게 구현한 이유는 스크립트를 보시면 아시겠지만 이동관련은 프레임단위로 인식되도록 해도 문제가 없지만

아이템사용같은 경우 1번키를 눌렀는데 프레임단위로 실행되버려서 한번에 3개를 사용해버리는 문제가 생깁니다.

버그가 일어나지 않도록 잘봐주십시다.

 

 

KeyTextChager.cs

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

public class KeyTextChanger : MonoBehaviour
{
    public Text[] txt; //텍스트

    void Start()
    {
        for(int i=0;i<txt.Length; i++)
        {
            txt[i].text = KeySetting.keys[(KeyInput)i].ToString();
        }
    }

    // Update is called once per frame
    void Update()
    {
        KeyTextChage(); //키 텍스트 바뀌는 함수
    }

    private void KeyTextChage()
    {
        for (int i = 0; i < txt.Length; i++)
        {
            txt[i].text = KeySetting.keys[(KeyInput)i].ToString(); //입력한 키로 바뀌는 함수
        }
    }

}

아까 KeyManager로 설정해준 키를 바꿔주는 스크립트입니다.

정확히는 인게임에서 보이는 UI인 텍스트에 적용해주는 스크립트로 Start함수를 보시면 텍스트에 아까 KeyManger에서 설정해준 키값들로 넣어주고 있습니다.

 

Update함수에는 키 입력을 바꾸는지 확인해주고있고

KeyTextChage()함수로 입력받은 키값을 UI에 시작적으로 표시해주도록 하고있습니다.

 

이렇게 각 텍스트를 넣어주시면 됩니다. UI가 Start함수로 인해 설정한 키로 보이게 됩니다.

실행전에는 안바뀌지만 실행해야 바뀝니다!

그리고 저 텍스트는 버튼에 있는 텍스트를 넣어준겁니다.


3. 결과

판넬에 스크롤뷰를 넣어서 왼쪽에는 기능의 텍스트와 오른쪽에는 버튼을 넣어서 버튼에는 KeyManager의 KeyChage함수를 적용시켜 버튼을 클릭해주고 변경할 키로 눌러주면 키변경이 가능해집니다.

 

이상입니다.