【Unity】InputFieldに入力された文字を出力したい

対象 Unity初心者

書いている人 書いてる時点でUnity2ヶ月目

前提 Unityでの基本操作がわかる

環境 M1Mac
Unity2019.4.17f1

InputFieldに文字を入力して、それを受け取ってどっかに表示したい。もしくは、受け取ったものを何かしらに使いたいなんていうことがあるかもしれない。これが割とややこしいので、自分なりに調べてみた。

今回はとりあえず、inputFieldに入力された文字を別の場所に出力する方法を見ていく。

目次

InputFieldと出力用のTextを用意する

まずは最初に、文字を入力する用のInputFieldと出力用のTextをHierarchy上に用意していこう。適当なプロジェクトを作成したら、Hierarchy左上のUIボタンをクリックして、inputFieldをクリック。同じ方法でTextも用意しておこう。

InputFieldやTextにはTextMeshProもあるが今回はノーマルのを使います。

Input Fieldを作成。同様にTextも用意しよう。

作成したら、自分の見やすいように場所などを移動しておこう。

上がInputField、下がText

Hierarchy上のTextの名前をわかりやすいようにDisplayTextと変更しておく。

TextをDisplayTextという名前に変更した

スクリプトを用意する

次はスクリプトを作成する。作ったスクリプトは正直どこにアタッチしてもよいと思うが、今回はInputFieldにくっつけようと思うので、InputFieldManagerとでもしておこう。

InputFieldManagerスクリプトを作成。
StartやUpdateは消しておいた。

作成したら、Hierarchy上のInputFieldにアタッチしておこう。D & D(ドラッグアンドドロップ)でもAdd Componentでも好きな方法で。

InputFieldにInputFieldManagerをアタッチ。

ここまでの「Scriptを作成したり、オブジェクトを作ったり、アタッチしたり」等のUnityの基本的操作がわからない人はとりあえずUnityの操作に慣れる為に、一冊本などをやってサンプルゲームを作ってみるといいかも。

スクリプトに書き込みをしていく

InputFieldManagerを作成してアタッチしたので、今度はこのスクリプトに以下のように記述していく。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class InputFieldManager : MonoBehaviour
{
    //出力用のテキスト
    public Text displayText;

    //inputFieldのOnEndEditに設定する用の関数
    public void OnEndEdit()
    {
        //InputFieldコンポーネントのtextを変数に代入
        string inputFieldText = GetComponent<InputField>().text;

        //出力用のテキストに代入
        displayText.text = inputFieldText;
    }
}

忘れちゃならないのが、UIをスクリプト上で使いたい場合にはUnityEngine.UIを書くこと。

これを書かないと、Text型などが使えない。

ではコードを一応上から見ていこう。

public Text displayText;の部分。これは箱をイメージしてほしい。型がTextなので、この箱にはTextクラスしか入れられない。

public Text displayText; の部分に、「入力内容を反映させたいText」をインスペクタ上から入れる。そして、使えるようにしていく。(今回だったら、DisplayText)。FindやTagで取得する方法などもあるが、手っ取り早いのでアウトレット接続にする。

次のpublic void OnEndEdit()これは関数だ。この部分が今回の目的である「InputFieldで入力した内容を出力する」という処理の部分だ。

関数の中のstring inputFieldText = GetComponent<InputField>().text;の部分。ここでInputFieldコンポーネントのtextを取得しているぞ。コンポーネントはUnityの重要な概念なので、わからない人はググろう。

InputFieldコンポーネントのTextを取得してる。(赤く囲った部分)

最後のdisplayText.text = inputFieldText;で取得してきたinputFieldTextを出力用のテキストに代入している。

スクリプトが書けたら、インスペクタ上で設定をしていこう。

変数displayTextにアウトレット接続をする

上で用意した変数、public Text displayText部分にHierarchyのDisplayTextを持っていく。pubicをつけることで、inspector上から設定できるようになる。

このNoneの部分に、、
Hierarchy上のDisplayTextをD & Dだ。

InputFieldコンポーネントのOnEndEditに関数を設定する

次は関数の設定だ。スクリプトの中でOnEndEdit関数を作成した。関数は作っただけじゃ勿論発動しない。どこかで、これを呼んであげないとダメだ。

これをどこで呼ぶかだが、InputFieldオブジェクトをクリックしたら、インスペクタ上から、InputFieldコンポーネントを確認してみてほしい。
下にスクロールすると、OnValueChangedOnEndEditがあると思う。

HierarchyからInputFieldをクリックして
インスペクタ上のInputFieldコンポーネントをチェック。下にスクロールしてみよう。

OnValueChangedはInputFieldに文字を打ち込んでいる最中に呼ばれる関数。

OnEndEditはInputFieldからフォーカスが外れた時に呼ばれる関数だ。

最初はOnEndEditの方にOnEndEdit関数をくっつけていこう。関数名は、わかりやすいように名前をつけただけで、OnEndEditっていう名前じゃなくてももちろん大丈夫だ。

以下のように関数を設定していこう。

On End Edit の+ボタンをクリック

+ボタンをクリック

クリックしたら、Noneになってるからここで使いたい関数を設定する。使いたいOnEndEdit関数はどこにアタッチされているかというと、InputFieldオブジェクトにアタッチされている。なので、NoneのとこにInputFieldオブジェクトをHierarchyからD&Dしよう。

Noneの部分に、、
InputFieldを持ってくる。

そしたら、No Functionの下矢印をクリックして、OnEndEdit関数を読んでこよう。

InputFieldManagerのOnEndEdit()を選択

これで関数も設定完了だ。
ポイントは「使いたい関数が書かれているスクリプトがアタッチされているオブジェクトを設定する」ことだ。

プレイして確かめてみる(OnEndEdit)

ここまで出来たら、後はプレイボタンを押して確かめてみる。

アルファベットを入力してEnterを押して成功。

ちゃんと反映された

日本語を入力してEnterを押して成功、、あれ?文字が消える。

Enter押したら消える。

なぜだか、日本語の場合Enter押したら文字が消えてしまう。

Enterではなく、クリックを外で行ったらうまくいった。

InputField外でクリックすればよさそう。

Mac上でビルドした時も日本語入力はうまくいかなかった。外でクリックしてもなんかバグる。

外をクリックしてもなんか文字が重なってだめだ。

InputFieldコンポーネントのOn Value Changedに関数を設定する

OnEndEditで確かめてみたので、今度はOnValueChangedで確かめてみたい。

今度はOnValueChangedに関数を設定してみる

さっきまでOnEndEditにOnEndEdit関数を設定していたので、−ボタンを押して削除しよう。

−ボタンをクリックすると、、
きれいさっぱりなくなる

−ボタンを押して、関数を削除したら、今度はOnValueChanedの方に関数を設定しよう。関数名がOnEndEditのままなので、本来名前としては適切でないと思うが今回は動きを確かめるなのでご愛嬌。

今度はOn Value Changedの方に関数を設定しよう。

プレイして確かめてみる(OnValueChanged)

OnValueChangedに設定したので、InputFieldに文字を入力する度にこの関数が発動するはずだ。つまりリアルタイムで入力した文字が反映されるはず。

アルファベットは成功!

日本語は、やっぱり反映されず、、

残念ながらOnEndEditに設定した状態と全く同じになった。

OnEndEditと同じでEnter押したら消えるし、リアルタイムで反映はされない

外側クリックしたら、反映されるところまで、OnEndEditと一緒だ。

バグなのか?

どうやら日本語の場合はダメみたいだ。先ほどと同じようにMac上でビルドしてみたが、うまく反映されなかったので日本語はダメみたい。

日本語入力の場合の解決策

一応、色々記事をググってみたところ、InputFieldコンポーネントのLintTypeをSingleLineからMultiLineNewlineに変更することで、日本語入力が可になるらしい。

LintTypeは初期でSingle Lineになってる
SingleLineをMultiLineNewlineに変更

MultiLineNewlineはEnter押した時に改行されるってことだ。これで実際にプレイしてみる。ちなみに関数はOnValueChangedに設定している。

日本語入力でEnterを押したら反映されるようになったが、リアルタイムでは変更されない。(OnValueChangedに設定してあるので本来ならリアルタイムに変更されるはずだが、、)

やはり、リアルタイムでの日本語入力は反映されないみたいだ。

MultiLineNewlineに設定すると、今度はアルファベット入力がうまく反映されなかったりもするので、素直にアルファベットのみを使うほうがいいかもしれない。

でも絶対Unityで作ったゲームで日本語入力した内容を受け取ったり、受け取ったテキストを使用できているはずなので、(そういうゲームたくさんあるよね?)どうにかやり方があると思うのだが、自分の力だとまだうまく出来そうにない。もっと調べて分かり次第追記予定です。

まとめ

  1. InputFieldのOnValueChangedとOnEndEditに実行したい関数を設定する
  2. OnValueChangedは入力している時に発動する
  3. OnEndEditはフォーカスが外れた時に発動する
  4. 日本語入力はEnter押した段階で消えてしまう

こんなところだろうか。悔しいが、日本語がうまく反映されないと自分がやりたいことが実装できない。しばらくは他のやり方で頑張るしかない。

おまけ

InputFieldの子オブジェクトのTextを取得する方法はダメ?

ここからは読まなくても大丈夫な部分だが、もし気になる人は読んでみてほしい。

最初に、自分がこの実装をどのように実行しようとしたのかというとHierarchy上のInputFieldの子オブジェクトのTextを取得してそれをにDisplayTextに反映するやり方だった。

ややこしいけど、InputFieldコンポーネントのテキストじゃなくて、InputFieldの子のTextオブジェクトを取得ってことだ。

Textオブジェクトを取得しちゃだめなの?

実際にこのやり方で動かしてみたが、OnValueChangedの方でなんかエラーがおきてうまくいかなかった。

なんか一字ずれる

たぶん素直にInputFieldコンポーネントのテキストを取得した方がよいと思う。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次