본 글은 TextMeshPro 3.0.6 버전 기준으로 작성 하였음.
텍스트 입력을 받는 용도로 TMP_InputField 라는 Component 가 있다.
https://docs.unity3d.com/Packages/com.unity.textmeshpro@3.0/api/TMPro.TMP_InputField.html
TMP_InputField 에서 입력 제한을 주는 방식이 여러 가지 있는데 여기서는 TMP_InputValidator 를 사용하는 방법에 대해 설명해 본다. (Inspector 에서 GUI 를 통해 설정하는 방법은 직관적이라 크게 문제가 안되는데, Programmatically 하게 구현하는 방식에 대한 설명은 부족함)
아래 코드는 TMP_InputField 에 TMP_InputValidator 를 통해 숫자만 입력 받을 수 있게 세팅하는 예제이다. (물론 숫자만 입력 받는 형태는 contentType 을 IntegerNumber 로 설정하면 되지만 예시를 위해서다)
TMP_InputField _inputField = null;
void Start() {
_inputField.inputValidator = new CustomValidator();
}
class CustomValidator : TMP_InputValidator
{
public override char Validate(ref string text, ref int pos, char ch)
{
if (Regex.IsMatch(ch.ToString(), @^[0-9]+$, RegexOptions.IgnoreCase) == false)
return (char)0;
switch (Application.platform)
{
case RuntimePlatform.WindowsEditor:
case RuntimePlatform.OSXEditor:
case RuntimePlatform.LinuxEditor:
case RuntimePlatform.WindowsPlayer:
text += ch;
pos += 1;
break;
default:
return ch;
}
}
}
TMP_InputValidator 의 Validate 를 override 해서 입력 가능 여부를 결정 하는데, 여기서 중요한 것은 Platform 구분이 필요하다는 것이다. Editor 와 Standalone 빌드에서는 text 와 pos 값을 변경해 주어야 정상적으로 반영이 되고, AOS, iOS 에서는 text 와 pos 값을 변경해 주면 2벌씩 입력되는 이슈가 발생한다.
TMP_InputField 코드를 열어보면 Append 라는 기능이 InPlaceEditing 의 return 값에 따라 다르게 작동 하는데,
protected virtual void Append(char input)
{
if (m_ReadOnly)
return;
if (InPlaceEditing() == false)
return;
...
}
InPlaceEditing 는 간단히 표현 하자면 터치식 키보드 이용 여부에 따라 값을 다르게 전달 하는 것으로 보인다.
private bool InPlaceEditing()
{
if (Application.platform == RuntimePlatform.WSAPlayerX86 || Application.platform == RuntimePlatform.WSAPlayerX64 || Application.platform == RuntimePlatform.WSAPlayerARM)
return !TouchScreenKeyboard.isSupported || m_TouchKeyboardAllowsInPlaceEditing;
if (TouchScreenKeyboard.isSupported && shouldHideSoftKeyboard)
return true;
if (TouchScreenKeyboard.isSupported && shouldHideSoftKeyboard == false && shouldHideMobileInput == false)
return false;
return true;
}
위 내용에 의해서 TMP_InputValidator 의 구현이 Platform 별로 다르게 해주어야 하는 것으로 추정된다.
참고로, inputValidator 기능을 사용하면 contentType 과 charaterVAlidation 값도 자동으로 바뀌게 된다.
public TMP_InputValidator inputValidator
{
get { return m_InputValidator; }
set { if (SetPropertyUtility.SetClass(ref m_InputValidator, value)) SetToCustom(CharacterValidation.CustomValidator); }
}
...
void SetToCustom(CharacterValidation characterValidation)
{
if (contentType == ContentType.Custom)
{
characterValidation = CharacterValidation.CustomValidator;
return;
}
contentType = ContentType.Custom;
characterValidation = CharacterValidation.CustomValidator;
}
버그인지 아닌지 모르겠지만, TMP_InputValidator 기능을 사용할 때는 Platform 별로 다르게 동작할 수 있음을 인지해야 한다.
참고로 Unity Forum 에서 찾은 Unity Technologies 가 알려준 TMP_InputValidator 의 사용 방법은 아래와 같다.
https://forum.unity.com/threads/tmp_inputvalidation-documentation.795237/#post-5769925
using UnityEngine;
using System;
namespace TMPro
{
/// <summary>
/// EXample of a Custom Character Input Validator to only allow digits from 0 to 9.
/// </summary>
[Serializable]
[CreateAssetMenu(fileName = "InputValidator - Digits.asset", menuName = "TextMeshPro/Input Validators/Digits", order = 100)]
public class TMP_DigitValidator : TMP_InputValidator
{
// Custom text input validation function
public override char Validate(ref string text, ref int pos, char ch)
{
if (ch >= '0' && ch <= '9')
{
text += ch;
pos += 1;
return ch;
}
return (char)0;
}
}
}
'Works > Unity 3D' 카테고리의 다른 글
Dependency Injection (0) | 2024.08.14 |
---|---|
ScriptableObject vs new Class (0) | 2024.05.21 |
Unity Sentis 설치 방법 (0) | 2023.08.18 |
Unity Muse (0) | 2023.08.16 |
Localization 에서 CSV 사용 Tip (0) | 2023.08.09 |
댓글