見出し画像

Unityやってみる05:【長文注意】Text(TMP)に、「Hello,World!」と表示させてみました

 こんにちは、Unity素人おじさんです。ただしプログラミング歴は結構長いです。

 いやあ、Unity難しいです(困惑w。

※前回はこちら:

 ただ、私があえて茨の道を歩んでいるのかもしれないな、というのは少し感じ始めています💦 最新のプログラミング環境であるUnityで、あえて古いスタイルを実験してみる必要は、ないのかもしれないですね。

 と、いいつつも、やはり私が最初に確認しておきたいことは、①複数のUI間でやり取りさせて、イベントを処理させる方法、②オブジェクト(ゲームオブジェクト)を動的に追加、削除する方法。

 で、今回は①複数のUI間でやり取りさせて、イベントを処理させる方法の実験です。

 Unityの「シーン(ゲーム空間)」に、ボタンとテキストオブジェクトを配置しておき、ボタンを押したらテキストオブジェクトに「Hello, World!」という文字が表示されるという、ごくごく簡単なものです。

 でもその簡単なものを実現するのに、6時間以上かかりました💦

 その苦労の実現の過程と注意点、「今回わかったこと」を、まとめました。


1.ボタンを押したら「Hello,World!」と表示させる

・まずUnity Hubを起動して、新規プロジェクトを作成します。エディターのバージョンの違いによって、できることできないことが違うかも知れません。私の使うエディターのバージョンはこれです。(2021.3.18f1)

 テンプレートは「3D コア」を選びます。テンプレは、今後自分の作りたいものを考慮して、選ぶといいですね。

 プロジェクト名は、「button_to_text」にしました。

 起動直後の画面です。今回、ボタンとテキストを使った実験ですので、その2つを置きます。オブジェクトの配置は、ヒエラルキーパネル(下の赤で囲った部分)でマウス右クリックして……、なのですけど、ここで重要な注意点があります。

まずボタンを配置します。ボタンの配置は、「UI」→「Button -TextMeshPro」、と選択します。

TMP(TextMeshPro)という、比較的新しい機能を持つテキストを追加した場合は、次の窓が開きます。「Import TMP Essentials」を押して、機能を有効にし、そのあと右上の「X」を押して、窓を消せばオッケーですね。


 ボタンがシーンビューに追加されました。が、ちっちゃすぎて見えないですね。ヒエラルキーパネルで、追加された「Button」というのをダブルクリックして、視点を移動してみましょう。

 ありました。オブジェクトの大きさや位置は、左上にあるツールを使って調整可能です。ここではその方法は省略します。

 で、問題は次、TEXTオブジェクトを追加する際の注意点です。

 どうもTEXTオブジェクト(TMP)には、2種類あるようで、どっちを使って配置するかで、挙動が違ってくることがあります。私はいろんなプログラム開発環境を使ったことがありますが、こんなわかりづらい仕様の環境は初めてです💦 たぶんですけど、Unityというのは日進月歩で進化しているので、2つのTEXTオブジェクトを完全に統合したいんだけどしきれてないんだと思います。その2つとは……。

①UI系のText(TMP)
 ヒエラルキーパネル上で、マウス右クリックのメニューから、「UI」→「Text - TextMeshPro」で配置します。
 

 ヒエラルキーパネル上では、「Canvas」という階層の下に、入れておく必要があります。そうしないとテキストが表示されません。なぜかというと、たぶん歴史的な事情だと思います。で、今回使用するのは、このUI系のText(TMP)です。なぜかというと、こちらでしかうまく動かなかったから。理由はよくわかりません💦

②3D系のText(TMP)

 こちらは、メニューの「3D Object」→「Text - TextMeshPro」で追加できるものです。どうももともと、UnityではUI系のテキストと3D系のテキストは全く別物だったようで、その名残りで2種類存在しているようです。シーンビューでは、UI系Text(TMP)とは違い、「Canvas」配下におかなくてもテキストが表示されますが、ゲーム画面でうまく表示されないという、よくわからない挙動が発生しています。ややこしい説明はここまでにしておきます。「テキストの書き換えをしたい場合は、UI系のText(TMP)を使う」、と覚えておけばいいと思います。

 で、追加したText(TMP)と、Buttonの表示文字としてのText(TMP)が、ヒエラルキーパネル上で、同じ名前になっています。簡単なサンプルの場合はいいですけど、大規模な開発をしていると、たぶん大混乱するでしょう。ちゃんと名前を変えてあげた方がいいですね。Unityでは、この辺の名前の変更については、あまり神経質にならなくてもいいようです。私がこれまで使ってきた開発環境では、だいたい「名前が重複してます! だめー!」、と怒られる所です💦

 まあせっかくなので、名前をちゃんと変更しておきましょう。オブジェクト名の変更は、「Inspector」パネルで可能ですね。
 Hello,World!表示用のオブジェクトを「Message_text」、Buttonに表示する文字を定義するためのオブジェクトを「Button_text」と名付けました。

 Message_textの文字を、「Please push button.」に変更しました。シーンビューで確認しながら、サイズや位置も調整しました。あらかた準備は出来たので、スクリプトの作成とイベントの定義をしていきましょう。

 考え方としては、下記の2つで実現可能です。

①「指定したテキストを、Hello,World!に変更する」というスクリプトを、どれでもいいのでオブジェクトに持たせておく。(ここではボタンオブジェクトに持たせます)

②その処理が、ボタンを押した時に実行されるように設定します。(ボタンオブジェクトのOnClick()という部分に、上記スクリプトおよび、実行させたい関数を指定します。

 言語化すると、結構ややこしいことをやる必要がありますね。ただ、それはUnityの弱点でもあるのですけど、逆に楽しい所でもある、というのが、少しずつわかってきました。他の言語みたいに、ガチガチにルールを決めて、縛りを増やしてしまうと、安全性とか堅牢さは増しますが、楽しくなくなっちゃうんですね。

 とまあ、いろいろ余計なことを考えてしまいますけど、話を進めましょう(笑。

 まずはボタンにスクリプトを追加しましょう。ヒエラルキーパネルでButtonを選び、inspectorパネルのずっと下の方にある、「Add Component」というボタンを押します。追加するものとして「New script」を選んで、名前を設定して「Create and add」ボタンを押します。名前は適当に、「ButtonPush」としておきます。

 ButtonPush(Script)というのが追加されました。その右の、「…」みたいなのをクリックするとメニューが開きます。一番下の、Edit Scriptを選びます。

 起動されるエディターは、人によって違うかも知れません。私の場合、Visual Studioが開きました。上の3行、using、という記述があります。このスクリプトで使う「オブジェクト」を指定するようです。他の言語でいう所の、ライブラリとかモジュールとかコンポーネント、みたいなものですね。

 で、その下にクラスの定義と、メソッドの記述があります。Start()、Update()という空のメソッドがあって、これはそのまま置いておいても大丈夫なんですけど、説明をシンプルにするために削除することにします。

 で、変更したのがこちら。「//」がついている、緑色のコメントのついた行が、私の追加したものです。
 まず、Text(TMP)を扱うために、TMProを追加。
 次に、クラスの定義の最初に、「TMP_Text」を使いますよ、その名前は「text」としておきますよ、と宣言 ([SeriailzeField]の部分です)。これ、何をやってるのかさっぱりわからなかったんですけど、とりあえず入れておきます。
 で、change_textというメソッドを追加して、宣言しておいたtextというオブジェクトに、SetTextという処理を施して、「Hello, World!」、と表示させます。
 と、いうことらしいのですけれど、釈然としない私(笑。
 「text」というオブジェクトの、参照先は指定しないでいいのだろうか、なぜnullを入れたままなのだろうか、と。

 それはすぐあとに判明しますので、ご安心ください。

 なお「change_text」の左側の青い宣言に、「public」、「void」とありますが、「public」というのは必須です。理由はずっと後で説明します。「void」は、「戻り値がない」という意味ですね。この関数(メソッド)は、ボタンのOnClickイベントで利用しますけど、OnClickイベントの呼び出し元には戻り値を渡しても処理できないため、voidにしておく必要があるのですね。という、難しい話はあまりしない方がいいですね(笑。

 で、上記を保存すると、Unityエディターにその内容が反映されます。で、ここが私にとって、驚愕だったのですけど、上のスクリプトで宣言した「text」という変数の参照を、Inspectorで設定できるようになっています。すっご(笑。いや、可能かどうかというと、可能なのはわかるんですけど、こういうインターフェースを考えつくのが、私にとっては衝撃です。
 まあ、そこはおいといて、「Text」という文字の、右の方の「None(TMP_Text)」という部分に、処理をさせたいText(TMP)を、ヒエラルキーパネルから、ドラッグ&ドロップしてくれば設定できるようです。やってみましょう。

 ヒエラルキーパネルから、「Hello,World!」と表示させる予定の、「Message_text」を選んで掴みます。

 それをスクリプトの、「Text」の右の青い部分に投げ入れます。

 できました! Textという変数に、処理させたいMessage_textを、紐づけることが出来ました。

 以上で、①「指定したテキストを、Hello,World!に変更する」というスクリプトを、どれでもいいのでオブジェクトに持たせておく、というのは完了です。

 次に、②その処理が、ボタンを押した時に実行されるように設定します。
 ボタンオブジェクトのOnClick()という部分に、上記スクリプトおよび、実行させたい関数を指定、というのを実施します。これが終われば「Hello,World!」を実行できる、はず!

 さっきMessage_textへの紐づけをした部分の、ちょっと上に「On Click ()」、というのが見えます。この下に「List is Empty(空だよ)」と表示されていますね。ここにさっきスクリプトで定義した、change_text()メソッドを、登録してやります。まず「+」というのを押して、メソッド登録の準備をします。


 右側の背景色ブルーの部分が、OnClick()イベント時に実行されるメソッドを、定義するための部分です。
 で、この処理が一番不可解で、なかなか覚えられないのですが、ボタンがクリックされた時に実行したい関数が、追加されたオブジェクトを、ヒエラリルキーパネルからドラッグ&ドロップします。
 今回の場合、ボタンオブジェクト自身にスクリプトを追加してあるので、自分自身(Button)をドラッグ&ドロップします。別に自分自身でなくても、カメラオブジェクトやライトオブジェクトに、スクリプトを追加してやってもいいですね。

 で、オブジェクトの登録が終わったら、そのオブジェクトが持っているメソッドの、どれをOnClick()時に実行させたいかを、選びます。
 ここで一つ注意です。実行させたいスクリプト(ここではButtonPush)がうまく表示されない場合は、設定するオブジェクトをミスっている可能性が高いです。表示されない場合、正しいオブジェクトを選んで、もう一度ドロップしてみましょう。正しいものが設定されている場合は、下のようにスクリプト名「ButtonPush」が、正しく表示されているはずです。

 では「ButtonPush」を選んでみましょう。

 ButtonPushにカーソルをあてると、そこから参照可能なプロパティー(属性)やメソッド(関数)が、ずらっと表示されますね。私が記述したメソッドである「change_text()」も表示されているので、それを選びます。

 設定されました!

 以上で準備は完了です。上部中央の、右向き▲を押すと、実行できます。実行すると、シーンビューからゲームビューに、自動でタブが切り替わり、ゲーム画面になります。やってみましょう。

 ボタンが表示され、「ボタンを押してね、てへ」、という文字が表示されました。ボタンを押してみましょう。

 やりました! 無事にHello,World!と表示できました!

 今回は非常に苦労しました💦

 ただ、苦労しただけの見返りはありました。

2.今回わかったこと

・Unityでは、ボタンのOnClick時の関数を、自由に定義できること。
・OnClick時の関数として設定するために、何かのオブジェクトにスクリプトを追加しておく必要があること。そのオブジェクト自体は、何でもいいこと。
・ただし外部から実行可能とするには、publicであること。また戻り値のないvoidで宣言されたメソッドであること。
・現在のUnityの、Text(TMP)は、内部的には二種類あること。今回はUI系のText(TMP)で実現できたけど、3D系のText(TMP)ではうまくいかなかったこと。
・UI系のオブジェクトは、ヒエラルキーパネル上では、Canvasという階層の下に、入れておくこと。

 いやー、やっぱりUnity難しい……、とも思いますけど、ローマは一日にしてならずですね。

 で、今後何をやろうかなあと考えたのですけど、下の絵のような、「モンスター飼育ゲーム(?)」を作ろうかなと思っています(笑。

 空中に浮かぶ、「モンスター生成」ボタンを押すと、シャワーのようなものからモンスターが出現し、落下して下のモンスター牧場に着地します。と、そこからは考え中なのですけど、まずはモンスター牧場と、その中に一匹のモンスター(ひとまず四角い、気ままにうごくオブジェクト)を配置したいと思います。

 ほんとは「動的なオブジェクト生成(シャワーの下に、モンスターを出現させる処理)」を、試したいのですけど、あまりあせらずのんびりやることにします。

 最後になりましたが侍Jのみなさん、準決勝での勝利おめでとう!
 何事もあきらめてはだめですね!
 私も、「まっくろくろすけ育成シミュレーション」完成まで、がんばります!(笑。

次回はこちら:

この記事が気に入ったらサポートをしてみませんか?