<게임 상의 KeyBoard를 이용하여 입력 받기>
- 로그인, 난이도 맵 선택 등 사용자로부터 VR 핸들러로 입력을 받기 위해 Keyboard 패키지를 다운로드 받아 사용하였다. (패키지: VR Keyboard)
- 문제: VR 핸들러로 Keyboard를 입력받는 예시 모두가 Text Field 예시로 우리가 사용하는 Input Field와 다른 예제였다. Input Field는 Text Field와 달리 사용자의 입력을 받는 이벤트가 발생하여야 하는데 EventSystem에 XRUI Input Modules로 VR Input을 받게 했음에도 입력되지 않았다.
- 해결: 따라서 Keyboard 패키지가 제공하는 코드의 일부분을 수정
<어떤 Field인지>
1. 사용자의 입력을 받아야하는 Input Field부분이 ID 부분인지 비밀번호 부분인지를 알 수 있도록 아래의 InputFieldManager코드에 아래와 같이 selectInputField 함수를 추가하였다.
2. 사용자가 VR기기로 IDInputField를 선택할때, selectInputField 함수가 실행되도록 On Select 함수이벤트에 selectInputField 함수를 추가한다.
3. 사용자가 Select를 하면 KeyboardManager의 InputObject가 해당 사용자가 선택한 Field가 되고 Keyboard가 해당 Field로 입력된다.
public class InputFieldManager : MonoBehaviour
{
public GameObject Keyboard;
public KeyboardManager keyboardM;
void Start()
{
Keyboard = GameObject.FindGameObjectWithTag("Keyboard");
keyboardM = Keyboard.GetComponent<KeyboardManager>();
}
void Update()
{
}
public void selectInputField()
{
Debug.Log($"InputField Selected: {transform.gameObject.name}");
Debug.Log($"Keyboard GameObject: {Keyboard}");
Debug.Log($"KeyboardManager : {keyboardM}");
keyboardM.InputObject = transform.gameObject;
}
}
InputFieldManager코드
<KeyboardManager에서 Keyboard 입력 받기>
1. KeyboardManager에서 Input을 get, set으로 아래와 같이 조작한다. Input을 아래와 같이 정의
private string Input
{
get
{
if (InputObject != null)
{
Component[] components = InputObject.GetComponents(typeof(Component));
foreach (Component component in components)
{
PropertyInfo prop = component.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
if (prop != null)
return prop.GetValue(component, null) as string; ;
}
return InputObject.name;
}
return "";
}
set
{
if (InputObject != null)
{
Component[] components = InputObject.GetComponents(typeof(Component));
foreach (Component component in components)
{
PropertyInfo prop = component.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
if (prop != null)
{
prop.SetValue(component, value, null);
return;
}
}
InputObject.name = value;
}
}
/*
get { return inputText.text; }
set { inputText.text = value; }
*/
}
2. Keyboard의 모든 Key가 입력될때마다 GenerateInput이 실행되도록 이벤트함수를 추가한 후 GenerateInput에서는 Input을 set한다.
void Start()
{
foreach (var key in keyList)
{
key.OnKeyClicked += GenerateInput;
}
capslockFlag = isUppercase;
CapsLock();
}
....생략
public void GenerateInput(string s)
{
if (Input.Length > maxInputLength) { return; }
Input += s;
ReactivateInputField(InputObject.GetComponent<InputField>());
}
3. 문제: 처음 위와 같이 했을때 Keyboard로 입력을 받았지만, 하나의 문자만 입력받고 이후 입력되는 문자는 입력받지 않는 문제가 발생하였다.
4. 원인: 알고보니 InputField가 처음 입력받은 후 Activate되지 않아 다시한번 InputField를 클릭해야 Field가 다시 활성화되서 입력되었다.
5. 해결: 다라서 Inpus을 set한 후 다시 InputField를 활성화 하도록 아래의 코드를 추가하였다.
void ReactivateInputField(InputField inputField)
{
if (inputField != null)
{
StartCoroutine(ActivateInputFiedlWithoutSelection(inputField));
}
}
IEnumerator ActivateInputFiedlWithoutSelection(InputField inputField)
{
inputField.ActivateInputField();
yield return new WaitForEndOfFrame();
if (EventSystem.current.currentSelectedGameObject == inputField.gameObject)
{
inputField.MoveTextEnd(false);
}
}
'Project > VR 기반 운전 시뮬레이션: 안전 "안전 운전만해" 프로젝트' 카테고리의 다른 글
[Part 16] 프로젝트 마무리 및 최종 보고서, Git (0) | 2022.05.15 |
---|---|
[Part 14] 3D 게임과 2D 화면 합치기: Canvas의 Render Mode (0) | 2022.05.15 |
[Part 13] VR 기기(Oculus Quest2)와 Unity 연동 (0) | 2022.05.15 |
[Part 12] 주차 성공에 대한 추가 코드 (0) | 2022.05.15 |
[Part 11] 채점 알고리즘 & Trigger, Collsion (0) | 2022.05.14 |