初心者がUnityでなんかしちゃうぞBlog

Unity初心者は、ゲーム開発の夢を見るか?

Unity初心者がクソゲーを作る その5 「会話イベントを作るにはどうすれば…?」

さぁ、作ろう。クソゲーを。

前回までのあらすじ

unity-senpai.hatenablog.com

初心者がチュートリアルの知識だけで3D探索ダンジョンもどきを作成中。 そろそろダンジョンらしいイベントを作りたくなってきたので、会話イベントの設計に挑戦。

会話イベントが欲しい

ということで、作ってみました。シンプルすぎる表示ですが文字があるとやっぱり違いますね。

f:id:yuu9048:20190124005114p:plain

しかし、この設計方法間違っている気がしてなりません。車輪の再発明になりかねないのでもう少し調べて作ってみたら良かったかも…? たぶん調べれば便利なAssetなり、プラグインなり、ソースコードなりがあると思うのですが、最初なのでとりあえず自力で作っていきたいと思います!

今回は当たり判定を使ってみた

今回は、プレイヤーキャラが「OnTriggerEnter」でイベントマスに侵入したらイベントを呼ぶというような仕組みにしてみました。
実際にオブジェクトを置かないといけないので非効率的な気がします。本当は座標を管理して、指定の座標に入ったらイベントを呼ぶみたいなほうがいいんですかね? よくわかりませんでした。

f:id:yuu9048:20190124005334p:plain

当たり判定を使うためには、当たる方か当たられる方のいずれかに「RigidBody」が必要となります。Player側に設定して「Is Kinematic」で物理演算を切っておきました。

f:id:yuu9048:20190124005838p:plain

次にイベントを起こしたい場所にColliderで当たり判定をつけたオブジェクトを置いておきます。「Is Trigger」を設定してこの範囲を踏んだら発火するようにしておきます。
ついでにTagに「Event」を作成して設定しておきました。タグ付けをしておいたほうが今後違うイベントを作るときとかにも役立ちそうなので。

これらの設定で、Player が Eventタグのついたオブジェクト の当たり判定に入ると処理が実行される下地が出来上がりました。

セリフUIを作る

どうやって作るのが正解かわからなかったので、GUIで作ってみました。

f:id:yuu9048:20190124010441p:plain

GUIの「Panel(MsgUI)」を作成し、ほどよきところに配置します。これがいわゆるメッセージ枠となります。その子要素に対して「Text」を追加してそこにメッセージ本文を設定します。

f:id:yuu9048:20190124010543p:plain

最初は表示しないので、非アクティブにしておきましょう。 ここで注意が必要なのが、非アクティブにしてしまったので「GameObject.Find」などでスクリプトからこのオブジェクトを見つけることができなくなりました

スクリプトのインスペクターからアタッチする形で参照できるようにしておきましょう!

スクリプトは単純明快!

今回のスクリプトは単純です。

プレイヤー管理のスクリプト

プレイヤーにアタッチするスクリプトで、当たり判定をキャッチします。「OnTriggerEnter」で当たり判定踏んだらこのメソッドが呼ばれます。 接触した相手のオブジェクトのタグが「Event」であれば、会話を表示するためのメソッドを呼び出しています。

    private void OnTriggerEnter(Collider other) {
        if (other.gameObject.tag == "Event") {
            gameDirectorObj.GetComponent<GameDirector>().showTalk("Hello");
        }
    }

ゲーム管理のスクリプト

ゲームの進行などを管理するスクリプトです。プレイヤー側が接触を感知すると呼び出されます。

    public void showTalk(string msg) {
        MsgUI.SetActive(true);
        MsgUI.transform.GetChild(0).gameObject.GetComponent<Text>().text = "オッハー!" + msg;
    }

今回注意したいのが、メッセージUIは「Panel」という親オブジェクトに対して、「Text」という子オブジェクトが存在しています。直接、親オブジェクトをいじっても文字列は変更できません。
ですので、2つの段階を踏みたいと思います。

MsgUI.SetActive(true);」で、非アクティブにしていたメッセージ表示用UIをアクティブ化して表示します。

MsgUI.transform.GetChild(0).gameObject.GetComponent().text」では、親オブジェクトの「MsgUI」に紐付けられている0番目、つまり最初の子オブジェクトである「Text」を参照しています。 そして、その子オブジェクト「Text」のコンポーネントのtextに文字列を打ち込んでいます。

実演

上記のメソッド呼び出しの引数に「Hello」を渡し、呼び出されたメソッドでは「オッハー」という文字列に引数でもらったメッセージを結合して表示していました。 ということでうまく動いているかを確認してみましょう。(都合によりgif動画は今回はありません)

f:id:yuu9048:20190124005114p:plain

セリフが変更されているので、無事動いているようです!