【Unity】Input Fieldの入力形式を制限する

こじゃらこじゃら

次のようにメールアドレスやパスワードなど決まった形式の文字列を入力させるにはどうすればいいの?

このはこのは

Input FieldのContent Typeを設定すれば良いわ。

編集可能なテキストのUIを提供するInput Fieldでは、入力可能な形式を制限したり修正したりすることができます。

例えば次のような入力形式が存在します。

形式の一覧
  • 整数入力を許容する
  • 小数入力を許容する
  • アルファベットと数字を許容する
  • 単語の先頭を大文字に変換して入力する
  • Emailアドレス形式の入力を許容する
  • パスワード入力(入力文字をアスタリスク「*」で伏せる)
  • PIN入力(アスタリスク「*」で伏せるが、数字入力のみ許容)
  • 独自の形式を定義して適用する

このような形式はInput Field側でプリセットとして提供されていますが、独自の入力形式や補正処理などを適用することも可能です。

また、このような機能は一部を除き、TextMesh Pro版、レガシー版両方のInput Fieldで使用可能です。 [1]

本記事では、Input Fieldの入力形式を制限したり、独自の形式を適用したりする方法について解説していきます。

動作環境
  • Unity 2022.1.15f1
  • Unity UI 1.0.0
  • TextMesh Pro 3.0.6

スポンサーリンク

前提条件

予めInput FieldがCanvasに配置されているものとします。

本記事ではTextMesh Pro版のInput Fieldを例にとって解説していきますが、レガシー版のInput Fieldでもほぼ同様の手順で実施可能です。

レガシー版Input Fieldの場合

入力形式の設定

TextMesh Pro – Input Field(レガシー版はInput Field)コンポーネントのContent Type項目を設定します。

設定可能な項目は以下の通りです。

Standardすべての入力を許容する。
Autocorrectedすべての入力を許容し、プラットフォームによるコレクト機能を有効にする。例えばiOSやAndroidなどでタイポ入力の自動修正が有効になる。
IntegerNumber整数(正または負)の入力のみ許容する。
DecimalNumber小数(正または負)の入力のみ許容する。例えば「123.456」など。
Alphanumericアルファベットと数字(A-Z、a-z、0-9)の文字入力のみ許容する。
Nameスペース区切りの単語の先頭のみ大文字となる入力となるように補正する。
EmailAddressE-mail形式の文字列の入力を許容する。例えば「name@domain」など。
Passwordすべての入力を許容し、入力した文字をアスタリスクで伏せる。
Pin数字のみの入力を許容し、入力した文字をアスタリスクで伏せる。
Customユーザー定義の設定を適用する。詳細な挙動の設定や、スクリプトでの定義などが可能。
Content Typeに設定可能な値

補正の挙動はTextMesh Pro版、レガシー版ともに一緒です。

参考:Input Field | Unity UI | 1.0.0

参考:Enum InputField.ContentType | Unity UI | 1.0.0

設定例

以下は、Content Typeを上から順にName、EmailAddress、Password、IntegerNumberの順に設定した例です。

実行結果

実際に文字列を入力したときの挙動です。

指定通りの挙動になりました。

カスタム定義を適用する

Content TypeにCustomを設定すると、より詳細な入力形式や修正処理を定義することができます。

この時、次のような項目が下に出現します。複数行やキーボードの種類などを設定できます。

設定項目について一通り解説していきます。

Line Type

単一行、複数行などの指定ができます。設定値によってのような振る舞いをします。

Single Line単一行、横スクロールの入力になります。
Multi Line Submit自動改行が有効になり、Submitキーで決定となります。
Multi Line Newline自動改行が有効になり、Submitキーで自由に改行できます。改行ありの文章を入力する場合はこの設定にします。

参考:Enum InputField.LineType | Unity UI | 1.0.0

Input Type

パスワード入力、自動修正などの指定ができます。

Standard標準的な入力。
Auto Correctモバイル環境などでの自動修正を有効にする。
Passwordパスワード形式の入力にする。入力した文字はアスタリスク「*」で伏字になる。

参考:Enum InputField.InputType | Unity UI | 1.0.0

Keyboard Type

主にタッチスクリーンなどで表示されるキーボードの種類を指定できます。

Default各種プラットフォームのデフォルトのキーボード配置。
ASCII CapableASCII配置のキーボード。
Numbers And PunctuationASCIIの数字のみの配置。
URLURL入力に適したキーボード。
Number Pad数字パッド。
Phone Pad電話番号入力に適したパッド。
Name Phone Pad個人名または電話番号入力に適したパッド。
Email AddressE-mailアドレスの入力に適したキーボード。
SocialTwitterなどのソーシャルメディア投稿に適したキーボード。「@」キーと「#」キーがある。
Search検索単語の入力に適したキーボード。「.」キーとスペースキーがある。
Decimal Pad小数点を含む数字の入力に適したパッド。
One Time Code標準的な数字パッドだが、PINコード入力などに適している。

参考:TouchScreenKeyboardType – Unity スクリプトリファレンス

実際に実機で検証した結果含め、より詳細な解説は以下記事でまとめております。

Character Validation

入力の検証方法を指定します。

Noneすべての文字を許容する。
Digit数字のみ許容する。
Integer整数(正または負)の入力のみ許容する。
Decimal小数(正または負)の入力のみ許容する。
Alphanumericアルファベットと数字(A-Z、a-z、0-9)の文字入力のみ許容する。
Nameスペース区切りの単語の先頭のみ大文字となる入力となるように補正する。
Regex正規表現で許容する文字を指定する。TextMesh Pro版限定。
Email AddressE-mail形式の文字列を許容する。
Custom Validatorカスタムの入力形式や補正処理を適用する。後述するTMP_InputValidator継承のScriptableObjectを実装して適用する形になる。TextMesh Pro版限定。

参考:Enum InputField.CharacterValidation | Unity UI | 1.0.0

スクリプトからの入力文字制御

ここまで解説した方法では、Input Fieldの設定項目から許容する形式や修正処理の挙動を定義していました。

このような制御は独自のスクリプトから行うことも可能です。onValidateInputイベントを使う方法TMP_InputValidator継承クラスを実装する方法の2通り存在します。

それぞれ使い方の注意点含め、使用例と共に解説していきます。

onValidateInputイベント経由で制御する

Input Field全体の挙動を独自のものに置き換える方法です。

TextMesh Pro版ではTMP_InputField.onValidateInputイベントレガシー版ではInputField.onValidateInputイベントに制御を行う処理を登録します。

// Input Field
// レガシー版はInputFieldクラスになる
TMP_InputField inputField = GetComponent<TMP_InputField>();

// イベント登録
inputField.onValidateInput += OnValidateInput;

onValidateInputイベントは文字入力を確認するタイミングで発火します。

参考:Class InputField | Unity UI | 1.0.0

onValidateInputイベントは次のような型(デリゲート)として定義されています。

public delegate char OnValidateInput(string text, int charIndex, char addedChar);

引数addedChar新しく入力された文字が渡ってくるため、現在の文字列が格納されている引数text、カーソル位置が格納されている引数charIndexなどを元に入力文字のチェックや置き換えなどを行います。

参考:Delegate InputField.OnValidateInput | Unity UI | 1.0.0

注意

onValidateInputイベントで制御した場合、Content Typeで設定した挙動が上書きされますのでご注意ください。

サンプルスクリプト

アルファベットと数字入力のみ許容し、アルファベットを大文字に置き換えるスクリプトの例です。

UpperLetterValidator.cs
using TMPro;
using UnityEngine;

public class UpperLetterValidator : MonoBehaviour
{
    // Input Field(レガシー版はInputFieldクラスに置き換える)
    [SerializeField] private TMP_InputField _inputField;

    private void Awake()
    {
        // イベント登録
        _inputField.onValidateInput += OnValidateInput;
    }

    // 入力された文字のチェックと変換
    private char OnValidateInput(string text, int index, char addedChar)
    {
        // アルファベットまたは数字でなければ入力しない
        if (!char.IsLetterOrDigit(addedChar))
            return '\0';

        // アルファベットの小文字なら大文字に変換する
        return char.ToUpper(addedChar);
    }
}

上記スクリプトをUpperLetterValidator.csという名前で保存し、適当なゲームオブジェクトにアタッチし、インスペクターより対象のInput Fieldを指定すると機能するようになります。

実行結果

アルファベットと数字以外の入力を受け付けず、入力したアルファベットの小文字は大文字に変換されるようになりました。

スクリプトの説明

以下部分でスクリプトによる制御を行っています。

// 入力された文字のチェックと変換
private char OnValidateInput(string text, int index, char addedChar)
{
    // アルファベットまたは数字でなければ入力しない
    if (!char.IsLetterOrDigit(addedChar))
        return '\0';

    // アルファベットの小文字なら大文字に変換する
    return char.ToUpper(addedChar);
}

char.IsLetterOrDigitメソッドは、引数に指定された文字がアルファベットか数字のときにtrueを返すメソッドです。

例ではfalseの時は入力を受け付けないようにしたいため、null文字「’\0’」をreturnしています。

null文字をreturnすると、入力された文字が破棄され、Input Fieldに反映されなくなります。

また、アルファベットを大文字に変換するために、char.ToUpperメソッドを使用しています。

InputValidator経由で制御する(TextMesh Pro限定)

TMP_InputValidator継承クラスを実装して制御する方法です。

TextMesh Pro版限定ですが、より細かな制御が可能です。

参考:Class TMP_InputValidator

TMP_InputValidatorはScriptableObjectであるため、アセットとして作成しておく必要があります。

サンプルスクリプト

先述の例をTMP_InputValidator継承クラスで実装するように変更したスクリプトです。

TMP_UpperLetterValidator.cs
using TMPro;
using UnityEngine;

[CreateAssetMenu(
    fileName = "UpperLetterValidator",
    menuName = "TextMeshPro/Create Upper Letter Validator",
    order = 0
)]
public class TMP_UpperLetterValidator : TMP_InputValidator
{
    // 入力された文字のチェックと変換
    public override char Validate(ref string text, ref int pos, char ch)
    {
        // アルファベットまたは数字でなければ入力しない
        if (!char.IsLetterOrDigit(ch))
            return '\0';
        
        // アルファベットの小文字なら大文字に変換する
        ch = char.ToUpper(ch);

        // 現在のテキストを更新
        text += ch;

        // 現在のカーソル位置を更新
        pos++;

        return ch;
    }
}

上記スクリプトをTMP_UpperLetterValidator.csという名前で保存しておきます。

適用手順

プロジェクトウィンドウで右クリックし、Create > TextMeshPro > Create Upper Letter Validatorの順に選択し、アセットを作成します。 [2]

該当するInput FieldコンポーネントのContent Type項目Custom、その下のCharacter Validation項目Custom Validatorを指定します。

そして、先ほど作成したアセットをInput Validator項目に指定します。

実行結果

ここまでの手順を成功させると、1つ目の例と同じ挙動になります。

もし別のスクリプトからonValidateInputイベントを拾って制御されている場合、挙動が上書きされてしまうためご注意ください。

スクリプトの説明

以下部分でTMP_InputValidator継承クラスを定義しています。

[CreateAssetMenu(
    fileName = "UpperLetterValidator",
    menuName = "TextMeshPro/Create Upper Letter Validator",
    order = 0
)]
public class TMP_UpperLetterValidator : TMP_InputValidator

また、TMP_InputValidatorクラスはScriptableObject継承クラスなので、ScriptableObjectアセットとして予め作成しておく必要があります。

これをメニューから可能にするために、CreateAssetMenu属性を指定してCreate > TextMeshProメニュー配下にCreate Upper Letter Validatorという項目を追加しています。

入力文字をチェックしたり変換したりするロジックは変わりませんが、現在のテキストとカーソル位置を自分で更新する必要があります。

// 現在のテキストを更新
text += ch;

// 現在のカーソル位置を更新
pos++;

さいごに

Input Fieldに入力可能な文字や形式、修正などの制御を行う方法について解説しました。

カスタム設定にするとより細かな設定が可能になります。スクリプトを活用することでより高度な入力制御も実現可能です。

参考サイト

スポンサーリンク