Unityで作ったメッセージ表示機能に選択肢機能を取り付ける

今回はUnityで作ったメッセージ表示機能に選択肢を選び、その後のメッセージを変更したり、アイテムを与えたりといった機能を作りたいと思います。

メッセージ表示機能は以前作成したものを改良して使います。

メッセージ表示機能のUI部分はそのまま使いますので、以下の記事を参照しUIを作成してください。

UnityでRPGゲームのメッセージ表示機能を作る
Unityでロールプレイングゲームのメッセージ表示機能を作成していきます。RPG以外でキャラクターの発言を表示したりする時にも使えます

最初に書いておきますが、使いやすくはないと思います。(^_^;)

今回の機能を作成すると以下のようなものが出来上がります。

スポンサーリンク

選択ウインドウの作成

メッセージ表示機能のUIは既に出来ていると思いますので、次は選択肢を選択する時のUIを作成していきます。

ヒエラルキーのMessageUIゲームオブジェクトを選択し、右クリックからUI→Panelを選択して名前をChoiceWindowとします。

シーンビューでShiftキーとAltキーを押しながら四隅の△を操作し、以下のようなサイズに調整します。

ChoiceWindowのサイズ

次にChoiceWindowを選択し、インスペクタのAdd ComponentからLayout→Vertical Layout Groupを選択して取り付けます。

これは選択ウインドウの子に配置したUI要素を縦に並べる為に使用します。

ChoiceWindowのインスペクタ

Child AlignmentをMiddle Centerにし、子のUI要素を真ん中に整列するようにします。

Control Child SizeのWidthとHeightにチェックを入れ、UI要素の幅と高さがChoiceWindowのサイズによってコントロールされるようにします。

Child Force ExpandのWidthとHeightにチェックを入れ、UI要素を強制的に幅と高さの拡張します。

次にヒエラルキーのChoiceWindowを選択し右クリックからUI→Legacy→Textを選択し、名前をTitleとします。

(注)今回は古いTextコンポーネントを使いますが、TextMeshProを使う場合はそれ用にスクリプトを書き替えてください。

さらにChoiceWindowを選択し、右クリックからUI→Panelを選択します。

ヒエラルキーのChoiceWindowの子のPanelを選択し、インスペクタのAdd ComponentからLayout→Horizontal Layout Groupを選択し取り付けます。

これはPanelの子に配置する選択ボタンを横に整列させる為に使用します。

選択ウインドウのPanelのインスペクタ

Spacingを20にし、Panelの子のUIの間隔を20にします。

Child AlignmentをMiddle Centerにし、Panelの子のボタンを真ん中に寄せます。

次にヒエラルキーのPanelを選択し、右クリックからUI→Legacy→Buttonを選択し、名前をYesButtonとします(以下の画像ではYesButton(Legacy)となってますが気にしないでください)。

YesButtonを選択し、インスペクタでWidthを100、Heightを30とします。

YesButtonのサイズ

ヒエラルキーのYesButtonを選択し、Ctrl+Dキーを押して複製し、F2キーを押して名前をNoButtonとします。

ここまででヒエラルキーは以下のようになります。

選択ウインドウの階層

またシーンビューでは以下のようになります。

選択ウインドウの見た目

YesButtonとNoButtonの子のTextに「はい」と「いいえ」を入力していますが、これは後でスクリプトから書き換えるので別に入力しなくてもいいです。

メッセージ表示機能スクリプトの改造

この記事の最初に紹介した記事内で作成したメッセージ表示機能のスクリプトを改造し、選択肢を選択する機能にも対応していきます。

新しくSelectionMessageスクリプトを作成し、MessageUIゲームオブジェクトに取り付けます。

以前に作成したMessageスクリプトが取り付けられている場合は削除してください。

ちょっとスクリプトが長いですし、重複する部分もありますが解説していきます。(^_^;)

messageTextはメッセージを表示するUIのテキストです。

messageは表示するメッセージです。

stringWhenYesIsSelectedListは選択肢で「はい」側のボタンを押した時に表示するリストです。

stringWhenNoIsSelectedListは選択肢で「いいえ」側のボタンを押した時に表示するリストです。

splitStringはメッセージを分割する時に使用する区切り文字です。

splitMessageは分割したメッセージを入れる文字列の配列です。

messageNumは分割したメッセージの何番目かを表します。

textDisplayIntervalは一文字を表示するまでの時間です。

elapsedTimeは前回の文字を表示してからの経過時間です。

nowTextNumはメッセージ中の今何文字目を見ているかの番号です。

clickIconは次のメッセージの表示を促すアイコンです。

clickFlashTimeはアイコンの点滅間隔です。

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

hasMessageは表示するべきメッセージがあるかどうかです。

messageWindowはMessageUIの子のPanelをヒエラルキーで設定します。

choiceWindowはChoiceWindowをヒエラルキーで設定します。

numOfSelectionsは選択を何回したかどうかです。

choiceTitleTextは選択ウインドウのタイトルのテキストをインスペクタで設定します。

yesButtonTextは選択ウインドウの「はい」側のボタンの子のテキストをインスペクタで設定します。

noButtonTextは選択ウインドウの「いいえ」側のボタンの子のテキストをインスペクタで設定します。

titleTextListは選択ウインドウが開いた時に選択肢のタイトルのテキストに表示する文字列のリストです。

yesTitleTextListは選択ウインドウが開いた時に選択ウインドウの「はい」側のボタンの子のテキストに表示する文字列のリストです。

noTitleTextListは選択ウインドウが開いた時に選択ウインドウの「いいえ」側のボタンの子のテキストに表示する文字列のリストです。

yesItemListは選択ウインドウで「はい」側のボタンを押した時にアイテムが得られる場合のアイテムのリストです。

noItemListは選択ウインドウで「いいえ」側のボタンを押した時にアイテムが得られる場合のアイテムのリストです。

choosingは今現在選択ウインドウが開いて選択肢のボタンを押す状態にいるかどうかです。

AwakeメソッドではclicIconに自身のゲームオブジェクトの子のPanel、その子のImageを取得し、そこからImageコンポーネントを取得し入れています。

messageTextには自身の子からTextコンポーネントを探し入れています。

Initializeメソッドを呼び出して初期化しています。

Initializeメソッドは後で作成します。

今回はメッセージ等を他のゲームオブジェクトのStartメソッドで設定する予定なので、それよりも前に初期化したい為にSelectionMessageスクリプトではStartメソッドではなくAwakeメソッドを使っています。

通常であれば会話等が発生する時にメッセージを設定するのでStartメソッドでも構いませんが、今回は問題があるのでAwakeを使っています。

Updateメソッドでは!hasMessageで表示するメッセージがない場合、またはchoosingがtrue、つまり選択状態にある時はこれ以降の処理をしません。

!isOneMessageでまだ表示するメッセージがある場合はテキストを表示するインターバル時間を経過時間が越えていた場合にメッセージを表示しています。

マウスの左ボタンが押された時は一気にメッセージを表示します。

!isOneMessageがfalseの時は1回に表示するメッセージを表示しているので、クリックアイコンを点滅します。

ここら辺は最初の記事と同じなので詳細はそちらを参照してください。

現在のメッセージが最後のメッセージの前のメッセージであり、かつ最後のメッセージが空文字の場合にDisplayTheChoiceWindowメソッドを呼んで選択ウインドウを表示します。

今回の場合はメッセージの最後が空文字である場合に選択ウインドウを表示する仕様にしています。

なので例えば

となっていれば「おはよう」のメッセージを表示し、マウスの左ボタンを押したら「こんにちは」のメッセージを表示し、「こんにちは」のメッセージを表示し終わったら選択ウインドウを開くという事になります。

選択ウインドウを開きたくない場合は文字列の最後の<>という記号を取り除きます。

マウスの左ボタンを押した時は次のメッセージを表示します。

分割されたメッセージの最後であればInitializeメソッドを呼んで初期化しています。

SetMessageメソッドはメッセージを設定するメソッドです。

メッセージが設定されたらメッセージウインドウを表示します。

OnPushButtonメソッドはボタンが押された時に実行するメソッドで引数でbool値を受け取り、trueかfalseかで処理を分岐します。

ボタンが押されたのでchoosingをfalseにし、選択ウインドウを非表示にします。

「はい」側のボタンが押されたら「はい」側のボタンが押された時に表示するメッセージを新しいメッセージとして設定します。

また「はい」を選択した時に得られるアイテムがあるならばアイテム取得処理を実行します。

今回の場合は文字列リストでどのアイテムが得られるかという文字情報だけをコンソールに表示していますが、List<Item>のように書き換えて実際にアイテム数を変更するような処理に変える事が出来ます。

「いいえ」側のボタンが押されたら「いいえ」側のボタンが押された時に表示するメッセージを新しいメッセージとして設定します。

ボタンが押されたらいずれにしてもnumOfSelectionsをインクリメントし、メッセージや選択ウインドウのUIのテキスト、選択した時に得られるアイテム等のリストの番号を変えます。

SetTheTitleTextOfTheChoiceメソッドでは最初にInitializeメソッドで初期化処理をし、他のスクリプトからメッセージ表示機能で使うリストを受け取りフィールドに設定します。

引数に渡すリストは別のスクリプトで作成します。

DisplayTheChoiceWindowメソッドでは選択肢の順番に応じて選択ウインドウで使っているテキストを書き換え、choosingをtrueにして選択状態にし、選択ウインドウを開きます。

Initializeメソッドではこのシステムでの初期化を行っています。

メッセージ表示機能にメッセージを渡すスクリプトの作成

次にテストのためにメッセージ表示機能にメッセージリストを渡すスクリプトを作成します。

ヒエラルキーで右クリックからCreate Emptyを選択し、名前をSetMessageとします。

SetMessageゲームオブジェクトに新しくSetMessageScriptスクリプトを作成し取り付けます。

messageは最初のメッセージのリストです。

<>があると一度マウスクリックする必要があります。

文字列の最後に<>がある場合は選択ウインドウを開きます。

文字列の最後に<>の記号がない場合はメッセージの終了なのでメッセージウインドウを閉じます。

stringWhenYesIsSelectedListは選択肢で「はい」側のボタンを押した時に表示するメッセージリストです。

stringWhenNoIsSelectedListは選択肢で「いいえ」側のボタンを押した時に表示するメッセージリストです。

titleTextListは選択ウインドウの選択のタイトルのリストです。

yesTitleTextListは「はい」側のボタンに表示する文字列のリストです。

noTitleTextListは「いいえ」側のボタンに表示する文字列のリストです。

yesItemListは「はい」側のボタンを押した時にアイテムを付与したい時のアイテムのリストです。

noItemListは「いいえ」側のボタンを押した時にアイテムを付与したい時のアイテムリストです。

アイテムのリストでアイテムを付与しない場合はそこを空文字にしておきます。

Startメソッドでは作成したリスト群をSelectionMessageスクリプトのSetTheTitleTextOfTheChoiceメソッドを使って渡しています。

最初に表示するメッセージはSetMessageメソッドで渡します。

他のメッセージを表示したい時のテストをする為にUpdateメソッドでマウスの右ボタンを押した時に新しいリストを作成し、再度メッセージを設定出来るようにしています。

通常であればメッセージを表示したいタイミングでメッセージリストをSelectionMessageスクリプトに設定するようにします。

ちょっと使いづらいかも!?

今回作成したい選択ウインドウを含めたメッセージ表示機能だと個々のリストの数は<>記号が文字列の最後にない場合以外はリストに同じ数だけの要素が必要になります。

リストの要素の数が違う場合はエラーで止まります。

また選択肢で選択した後にstringWhenYesIsSelectedListとstringWhenNoIsSelectedListのメッセージを表示して表示するメッセージを変える事が出来ますが、その後、文字列の最後に<>がきて再度選択ウインドウを開いた時に以前の「はい」「いいえ」の選択にかかわらず次の選択肢のタイトル、「はい」側のボタンのテキスト、「いいえ」側のボタンのテキストは同じ物が表示されます。

なので

「はい」を押す、「はい」側のメッセージ、次の「はい」側の選択肢、という流れには出来ません。

「はい」を押す、「はい」側のメッセージ、次の共通の選択肢という流れになります。

終わりに

複雑に分岐したメッセージ機能にする場合は今回の機能は使い勝手は良くありません。

そういう場合はメッセージの表示が終わった時に選択肢のタイトル、「はい」側のボタンテキスト、「いいえ」側のボタンテキストを渡し、選択し終わったら表示するメッセージを渡し、と逐一メッセージを渡していくやり方がいいかもしれません。

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