본문 바로가기
Works/Unity 3D

[Unity] TMP_InputField 의 inputValidator 사용법

by Vader87 2023. 9. 7.
반응형

본 글은 TextMeshPro 3.0.6 버전 기준으로 작성 하였음.

텍스트 입력을 받는 용도로 TMP_InputField 라는 Component 가 있다.

https://docs.unity3d.com/Packages/com.unity.textmeshpro@3.0/api/TMPro.TMP_InputField.html

 

Class TMP_InputField | TextMeshPro | 3.0.6

Class TMP_InputField Editable text input field. Namespace: TMPro Assembly : solution.dll Syntax [AddComponentMenu("UI/TextMeshPro - Input Field", 11)] public class TMP_InputField : Selectable, IMoveHandler, IPointerDownHandler, IPointerUpHandler, IPointerE

docs.unity3d.com

TMP_InputField 에서 입력 제한을 주는 방식이 여러 가지 있는데 여기서는 TMP_InputValidator 를 사용하는 방법에 대해 설명해 본다. (Inspector 에서 GUI 를 통해 설정하는 방법은 직관적이라 크게 문제가 안되는데, Programmatically 하게 구현하는 방식에 대한 설명은 부족함)

아래 코드는 TMP_InputFieldTMP_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

 

TMP_InputValidation documentation

I can't find any info anywhere about how to actually implement the "Validate()" method of TMP_InputValidator....

forum.unity.com

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

댓글