InputField の日本語入力とスクロールブロック対応

imatomix
2022年3月17日 10:14

概要

image

Unityで上記のようなのInputField(ここではTextMeshPro-InputField)が並んだUIを作成しているときに、以下の不具合がありました。
  • Macだと日本語入力がうまくいかない。
  • InputFieldのLine Type を Multi Line Newline にするとうまくいく。
  • しかし、
  • 改行ができてしまう。
  • スクロールがInputFieldにとられるようになり、InputField上ではページのスクロールができなくなる。
この辺りの対応策を模索してみました。

対応策

UniRxを使用しています。

改行できてしまう。

  • 単純に、入力された文字列から改行を抜き取る処理を入れる。
InputFieldUtils.cs
using UnityEngine; using UnityEngine.UI; using TMPro; using UniRx; public class InputFieldUtils : MonoBehaviour { [SerializeField] TMP_InputField inputField; void Start() { inputField.onValueChanged.AsObservable() .Subscribe(value => inputField.text = value.Replace("\n", "")); } }

スクロールがInputFieldにとられてしまう。

multi Line タイプのInputFieldは内部にスクロール処理をもっているので、それが処理を奪ってしまいページのスクロールを効かなくなってしまっている。InputFieldのRaycastTargetを全てオフにして回避すると、InputFieldが選択できなくなるので、別オブジェクトとスクリプトで選択できるようにする。手順は以下の通り、
  • UI > Image オブジェクトを追加し、 InputField の親にする。
  • InputFieldのImageコンポーネントは削除し、TargetGraphicに親のImageコンポーネントを指定する。
  • InputField以下の Placeholder と Text オブジェクトの TextMeshPro-Text コンポーネントにある Raycast Target をオフにする
  • Caretは動的に生成されるので、スクリプトから Raycast Target をオフにする。
  • 親のImageがクリックされたらInputFieldのSelect()を実行する。
InputFiledUtil.cs
using UnityEngine; using UnityEngine.UI; using TMPro; using UniRx; using UniRx.Triggers; public class InputFieldUtils : MonoBehaviour { [SerializeField] TMP_InputField inputField; [SerializeField] Image background; // 親のイメージコンポーネント void Start() { TMP_SelectionCaret selection = inputField.GetComponentInChildren<TMP_SelectionCaret>(); selection.raycastTarget = false; // CaretのRaycastをオフにする。 background.OnPointerClickAsObservable().Subscribe(_ => { inputField.Select(); }); inputField.onValueChanged.AsObservable() .Subscribe(value => inputField.text = value.Replace("\n", "")); } }

感想

やってみたら意外とめんどくさかった。InputFieldをオーバーライドする形でもっと綺麗にできそうな気がする。