UnityでRPGゲームのメッセージ表示機能を作る

今回はRPGゲーム等でよく使われるメッセージ表示機能を作りたいと思います。
誰かと話した時に、その会話の内容を表示する部分です。

大まかな仕様として、表示したい会話の内容を一定秒数後に一文字づつ表示していく。

全部の会話文字列の間に分割する文字列を入れておき、1回で表示するメッセージを指定出来るようにする。

また、文字を表示している間にマウスクリックをしたら、1回で表示出来る文字数分を一気に表示するクイック表示機能をつける。

表示したい会話の内容がなくなった場合、マウスクリックでメッセージ画面ごと消す。

こんな感じの仕様にします。

2019/07/02に全面的に機能を簡略化し、より使いやすくしました。

スポンサーリンク
スポンサーリンク

メッセージ表示用のUIを作成

まずはメッセージを表示する場所を作成します。

ヒエラルキーにCreateからUI→Canvasを作り、名前をMessageUIとします。
MessageUIの子要素にUI→Panelを作り、その子要素にUI→Text、UI→Imageを作成します。

メッセージ1

上のような感じの階層を作成します。

RPGの会話メッセージ表示領域

大枠がPanelで、それより少し小さくTextを作成します。Imageは右下に配置します。

Imageはクリックを促すアイコンになるのでインスペクタのSource ImageでSpriteを設定してください。

TextをPanelより少し小さくしたのは、同じ大きさにすると枠ギリギリに表示されてしまうので見づらくなる為です。

メッセージ表示のTextの設定

Textのインスペクタで設定を上のようにします。

Textは親のPanelのサイズに合わせて大きさを変え、Panelの枠から10ピクセル内側になります。

Alignmentは左上を指定し、左上から会話が表示されるようにします。
Horizontal OverflowはWrapにし、横幅を超える文字があった場合自動で次の行に表示します。
Vertical OverflowはTruncateにします。Truncateにすると縦幅を超える文字があった場合表示しません。
Overflowに設定すると、指定した文字は枠を超えて表示されるようになります。

ここの設定は自由に設定してください。

Best Fitにチェックを入れると枠に応じて制限内で文字の大きさが自動で変更されます。
制限値はBest Fitにチェックを入れると、Min SizeとMax Sizeの指定が出来ます。
しかし、メッセージは統一した文字の大きさで表示したいので、今回はチェックを入れません。

メッセージ表示スクリプトMessageを作成

メッセージを表示するスクリプトMessageを作成します。

MessageスクリプトはMessageUIゲームオブジェクトに設定します。

messageTextはメッセージを表示するUIのTextを後で設定します。

allMessageは村人と話した時に会話する全内容を設定します。

\nで改行、<>はデフォルトの1回に表示する会話の分割に使う文字列です。

[TextArea(1, 20)]アトリビュートはインスペクタで最低1行で表示を20行にし、それより多い分はスクロールして見れるようにします。

allMessageはインスペクタでも設定出来ます。

splitStringは全会話内容を1回で表示するメッセージに分割する時の分割文字列を設定します。デフォルトでは<>にしています。

splitMessageは全会話内容を1回に表示するメッセージ事に分割して配列にして入れます。

messageNumはsplitMessageの今何番目のメッセージかを表しています。

textSpeedはテキストを表示する速さ

elapsedTimeは次のメッセージを表示するまでの経過時間やアイコンの点滅の経過時間を入れます。

nowTextNumは現在の1回で表示するメッセージの何番目の文字かです。

clickIconはクリックを促すアイコンを指定します。

clickFlashTimeはクリックを促す時に点滅する間隔です。

isOneMessageは1回で表示するメッセージを表示したかどうか

isEnbMessageは全ての会話が終了したかどうかです。

StartメソッドではクリックアイコンImageの取得や会話を表示するTextの取得、SetMessageで会話内容のセットをしています。

Updateメソッドを見ていきます。

会話が終了している時、または会話が設定されていない時はreturnでそれ以降の処理をしません。

isOneMessageで1回のメッセージを表示していない時で経過時間がtextSpeedを越えたら現在見ている1回に表示するメッセージ(splitMessage)の今見ている文字をmessageTextに足します。

現在見ている文字番号が現在見ている1回に表示するメッセージ(splitMessage)の最大値を越えていた時は1回のメッセージは全て表示したのでisOneMessageをtrueにします。

メッセージ表示中にマウスの左ボタンを押したら現在までに表示している文字列にsplitMessage[messageNum].Substring(nowTextNum)で残りの文字列を足して1回に表示するメッセージを全て表示します。

StringクラスのSubstringメソッドは引数で指定した文字の位置以降を求めることが出来ます。

例えば

とすればコンソールに est が表示されます。

Substringメソッドは第2引数を渡すことも出来、第1引数で指定した文字位置から第2引数で指定した文字数分を取得することが出来ます。

一回に表示するメッセージ(isOneMessage)がfalseの時はクリックアイコンを点滅させ、マウスの左ボタンが押されたら初期化処理をして次のsplitMessageを表示していきます。

全てのsplitMessageを表示しきったらisEndMessageをtrueにし、子要素のパネルを非アクティブにします。

SetMessageメソッドは全ての会話文を引数で受け取り、それを1回で表示するメッセージに分割して配列にします。

Regex.Splitを使ってallMessageをパターンで分割し配列にしています。

分割文字列はsplitStringの文字と前後に\s*を付けて『空白文字列splitString空白文字列』というパターンを分割文字列としています。

SetMessageメソッドが呼ばれる時は別の人と話す時など会話が一新される時なので、初期化処理をしています。

SetMessagePanelは外部のスクリプトから再びメッセージを表示する時に使用します。

今回はサンプルなのでヒエラルキー上に空のゲームオブジェクトを作成し、名前をActiveMessagePanelにし、これにActiveMessagePanelスクリプトを取り付け、ここから新しいメッセージを設定出来るようにしてみます。

ActiveMessagePanelスクリプトはマウスの右ボタンを押したらMessageスクリプトのSetMessagePanelにメッセージを設定して、呼び出します。

今回はマウスの右ボタンを押してメッセージを設定していますが、普通ならば村人と会話を開始するというイベントのタイミングでMessageスクリプトのSetMessagePanelを呼び出せばいいと思います。

Messageスクリプトの設定

上ではMessage2という名前になっていますが、これはわたくしの都合上そうなっているだけです。

Unityの実行ボタンを押して確認してみましょう。

メッセージ5

上のようになりました。

メッセージ機能の問題点

以前作成した機能だと1回に表示するメッセージの分割が難しかったり、処理が少し複雑になっていたので、

それらを解消しました。

少し注意が必要なのが、1回に表示するメッセージ用の分割文字列を入れないとUIの設定上文字が見えなくなったりします。

allMessageには区切りの良い所で区切り文字列を入れてください。

区切り文字列はデフォルトで<>としていますが適宜変更してください。

またallMessageをインスペクタでも設定出来るようにしましたが、コンポーネントの歯車のResetを選択した時はスクリプトで記述したallMessageの内容が上書きされます。

なのでスクリプト中で正しい会話内容を指定しておいた方がいいです。

逆にスクリプト中のフィールド等の設定値はコンポーネントの歯車のResetでインスペクタでも反映されます。

コメント

  1. kt より:

    こんにちは、初心者の私にも分かりやすいコードで使用させていただきました。
    会話中にキャラクターの動きを停止させれる方法などもあれば希望したいのですが(←何様
    楽しんで他記事も読ませていただきます!

タイトルとURLをコピーしました