ユニティちゃんのRPGを作ってみよう5ー村人との会話ー

今回はユニティちゃんが村人と会話出来る機能を作成していきます。

今回の機能はちょっと難しいかも?しれません。

前回は村人が巡回ポイントを移動するようにしました。

ユニティちゃんのRPGを作ってみよう4ー村人の移動ー
ユニティちゃんのRPGで村人を配置しナビゲーション機能を使って村の中を歩き回る機能を作成していきます。

ユニティちゃんのRPGを作ってみようの他の記事は

ユニティちゃんのRPGを作ってみよう
ユニティちゃんのRPGを徐々に作っていくカテゴリです。

から見ることが出来ます。

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

村人との会話機能

村人との会話機能を作成していきます。

村人が会話する範囲を作成

まずは村人が会話をする範囲を作成していきます。

Villagerゲームオブジェクトを選択し右クリックからCreate Emptyを選択しSearchAreaという名前にします。

SearchAreaのインスペクタのAdd ComponentからPhysics→Sphere Colliderを取り付け、Is Triggerにチェックを入れ衝突をせず検知するようにします。

このコライダがユニティちゃんと会話する範囲になります。

Sphere ColliderのCenterとRadiusを設定しコライダの範囲を調整します。

ユニティちゃんRPGの村人の会話が出来る範囲

村人の会話が出来る範囲は以下のようにしました。

ユニティちゃんRPGの村人の会話が出来る実際の範囲

会話範囲に入った時に実行するスクリプト

先ほど村人が会話する範囲を作成しましたが、その範囲内に入った時の処理をスクリプトで作成していきます。

Assets/RPG/Scriptsフォルダ内で右クリックからCreate→C# Scriptを選択し、名前をConversationScopeScriptとし、SearchAreaゲームオブジェクトに取り付けます。

OnTriggerStayで範囲内にPlayerタグを持ったコライダでそのコライダのUnityChanScriptのGetStateメソッドを呼び出し、ユニティちゃんが会話している時でなければそのコライダからUnityChanTalkScriptのSetConversationPartnerメソッドを呼び出し自身のゲームオブジェクトを渡します。

OnTriggerExitでPlayerタグを持つコライダでユニティちゃんの状態が会話状態でない時に範囲外に出たらResetConversationPartnerメソッドに自身のゲームオブジェクトを渡し会話相手から外します。

ここでPlayerタグを設定したコライダでユニティちゃんを判定しているので、UnityChanゲームオブジェクトを選択し、インスペクタのTagをPlayerにします。

ユニティちゃんのTagをPlayerに変更する

ここでUnityChanScriptのGetStateメソッドを呼び出して状態の判定をしていますが、UnityChanScriptの状態を表す列挙型や状態を取得するGetStateメソッド等は後で作成していきます。

UnityChanTalkScriptも後で作成します。

会話表示用UIの作成

会話表示用のUIを作成していきます。

ヒエラルキー上で右クリックからUI→Panelを選択し、作成されたCanvasの名前をTalkUIとします。

Panelを選択した状態で右クリックからUI→Image、UI→Textを作成します。

ユニティちゃんRPGの会話表示用UI

シーンビューでPanelの四隅の矢印をShiftキーを押しながらドラッグし、会話表示部分の範囲を作成します。

ユニティちゃんRPGの会話表示部分のサイズ

上のような感じにしました。

TextはAnchor Presetsでstretch stretchにし、Panelのサイズに合わせて伸縮するようにします。

ImageはAnchor Presetsをbottom rightにし、Panelの右下に表示されるようにします。WidthとHeightは30にします。

またTalkUIはゲーム画面のサイズに合わせて拡張したいのでUI Scale ModeをScale With Screen Sizeにします。

Reference Resolutionは基準となる画面の解像度でXを1024、Yを768としておきます。

Screen Match ModeはExpandとします。

ユニティちゃんRPGのTalkUIをゲーム画面サイズに合わせて拡張する

細かいUIの作成方法やこの後作成するユニティちゃんの会話機能は

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

の方で解説していますのでそちらを参照してみてください。

TalkUIは会話する時だけ見えるようにする為、TalkUIのインスペクタの名前の横のチェックを外し、最初は見えないようにしておきます。

会話可能アイコンUIの作成

次はユニティちゃんが村人と会話が可能である時(村人のSearchAreaのコライダの範囲内にいる時)に表示する会話を促すアイコンのUIを作成します。

ヒエラルキー上で右クリックからUI→Panelを選択し、Canvasの名前をTalkIconにします。

TalkIconを選択した状態で右クリックからUI→Panelを選択します。

PanelのAnchor Presetsをmiddle centerにし、Widthを200、Heightを70にします。

またAdd ComponentからLayout→Horizontal Layout Groupを取り付けます。

ユニティちゃんRPGのTalkIconのPanelの設定

設定は上のような感じにします。

Imageは使用しないので横のチェックを外しておきます。

Horizontal Layout Groupは子要素を横並びに整列させる機能です。

Panelの子要素にUI→Imageを作成します。

ImageのAnchor Presetsでmiddle centerにしWidthとHeightを50にします。

ImageのSource Imageには押すべきボタンのアイコンを指定します(今回は適当なアイコンを設定しています)。

ユニティちゃんRPGのTalkIconのImageの設定

Textのインスペクタは下のようにWidthやHeightを設定し、テキストのサイズと色を変化させています。

ユニティちゃんRPGのTalkIconのTextの設定

TalkIconも村人と会話が可能な時だけ見えるようにする為、TalkIconのインスペクタの名前の横のチェックを外し最初は見えないようにしておきます。

ユニティちゃんの会話処理用スクリプトを作成

先ほどConversationScopeScriptでUnityChanTalkScriptのメソッドを呼び出していますのでそのスクリプトを作成していきます。

ユニティちゃんの会話処理スクリプトUnityChanTalkScriptをAssets/RPG/Scriptsの中に作成しUnityChanゲームオブジェクトに取り付けます。

conversationPartnerは会話相手を保持して置くフィールド、talkIconやTalkUIは先ほど作ったゲームオブジェクトをインスペクタで設定します。

その他フィールドやUpdateメソッドの会話を表示する処理の詳細は

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

上の記事で詳しく書いていますので、そちらを参照してください。

今回はInput.GetButtonDown(“Jump”)でJumpに割り当てられているボタンを押した時にメッセージの一括表示や次のメッセージの表示をするようにしています。

ボタンの割り当てはUnityメニューのEditからProject Settings→Inputで設定出来ます。

メッセージ表示機能以外の部分を見ていきます。

LateUpdateメソッドはUpdateメソッドと同じように毎フレーム呼ばれますが、Updateより後に呼ばれます。

会話相手がいる場合はtalkIconの位置を会話相手の頭上に表示させています。

Camera.main.GetComponent().WorldToScreenPointでメインカメラのCameraコンポーネントのWorldToScreenPointメソッドを使って引数で与えられたワールド位置をカメラのスクリーンの位置に変換しています。

こうすることでTalkIconのサイズが変更せず会話相手が移動してもそのワールド位置をカメラのスクリーンの位置に変換し移動するようになります。

SetConversationPartnerメソッドはtalkIconを表示して、会話相手を設定します。

ResetConversationPartnerメソッドは引数でリセットする会話相手が渡ってきますが、会話相手をリセットするのは保持している会話相手と引数で受け取った会話相手が一致した時だけです。

会話相手が設定されていなかったり、他の村人が会話相手として設定されている時に別の村人を引数で受け取っても会話相手はリセットしません。

GetConversationPartnerメソッドは会話相手を返します。

StartTalkingメソッドはユニティちゃんが会話相手と会話する時に呼び出されるメソッドで会話するのにあたっての初期化処理をしています。

conversationPartnerには会話相手の村人のゲームオブジェクトが入っているので、GetComponetでVillagerScriptを取得出来ます。

VillagerScriptのSetStateメソッドを呼び出して村人の状態を変化させます。

同時に村人の会話内容を保持しているスクリプトをGetConversationメソッドで取得しGetConversationMessageメソッドで実際の会話内容の文字列を取得します。

ユニティちゃんが村人と会話を開始するのは村人の会話範囲にいる時にJumpに割り当てられたボタンを押した時に始めますが、その際のキー入力を会話を進める時にも使っています。

そこでInput.ResetInputAxesメソッドを呼び出して一旦リセットし、会話を進める時はもう一度Jumpボタンを押す必要があります。

会話が終了した時はEndTalkingメソッドを呼び出し、そこで村人とユニティちゃんの状態を変更しています。

UnityChanゲームオブジェクトのUnityChanTalkScriptの設定は

ユニティちゃんRPGのUnityChanTalkScriptの設定

上のように設定しました。

UnityChanScriptに処理を追加

UnityChanScriptに会話している状態を作る為に処理を追加します。

ユニティちゃんの状態を表す列挙型Stateを作ります。

ユニティちゃんの状態を保持するstateフィールド、UnityChanTalkScriptを保持するunityChanTalkScriptフィールドを宣言します。

Startメソッドではユニティちゃんの状態の初期化とUnityChanTalkScriptを取得しておきます。

次にUpdateメソッド内の処理をユニティちゃんの状態に応じて変化させます。

State.Normal状態の時は今までと同じように移動処理を行い、その中でUnityChanTalkScriptのGetConversationPartnerメソッドで会話相手がいるかどうか調べ、いる時でJumpボタンを押したら状態をState.Talk状態にします。

State.Normal状態であろうとState.Talk状態であろうと重力は働かせます。

次に状態変更と初期処理を行うSetStateメソッドを追記します。

引数で受け取った状態を保持し、ユニティちゃんが会話状態になった時は移動速度velocityを0にし、アニメーションパラメータのSpeedを0にしてアニメーションをIdleにし、unityChanTalkScriptのStartTalkingメソッドを呼び出して会話を始めます。

状態を取得するGetStateメソッドを追加します。

状態フィールドstateを返しているだけです。

村人の会話内容ファイルを作成する

村人の会話内容はスクリプト中のstringフィールドで各自保持しておくことも出来ますが、今回はScriptableObjectを使ってあらかじめアセットファイルとして会話内容を作っておき、それを入れ替えるだけにします。

ScriptableObjectやあらかじめアセットファイルを作っておく方法は

UnityのScriptableObjectを使う
UnityのScriptableObjectを使うと、メモリの節約が出来たり、シーン間の移動でデータを共有するのが簡単になります。この記事では基本だけを記述しています。

UnityでScriptableObjectを使ってアイテムデータベースを作成する
UnityでScriptableObjectを使ってアイテムデータベースを作成し、そこからアイテム情報を引き出せるようにします。

も参照してください。

Assets/RPG/Scriptsフォルダ内で右クリックからCreate→C# Scriptを選択し、名前をConversationとします。

Conversationはただ単に会話内容をmessageフィールドで保持して置くだけのスクリプトです。

CreateAssetMenuアトリビュートを取り付けたことでUnityメニューのAssetsからこのConversationファイルを作成することが出来るようになりました。

fileNameは作成されるファイル名で、menuNameはAssets以下で表示される項目の名前です。

Assets/RPGフォルダ内で右クリックしCreate→Folderで名前をDataとしその中で右クリックからCreate→Folderで名前をConversationとします。

Conversationフォルダ内で右クリックしCreate→Folderで名前をFirstVillageとします。

FirstVillageフォルダ内で右クリックからCreate→CreateConversationを選択するか、

UnityメニューからConversationファイルを作成する方法

UnityメニューのAssetsからCreate→CreateConversationを選択するとConversationファイルを作成できます。

Assetsフォルダ内でConversationファイルを作成する方法

どちらかの方法でファイルを作成するとConversationというファイルが出来るので選択した状態でF2キーを押して名前をVillagerAとし、Ctrl+Dキーをおして複製し名前をVillagerBとします。

ユニティちゃんRPGの会話で使用する会話内容ファイル

VillagerAとVillagerBのインスペクタでそれぞれ会話内容を記述します。

ユニティちゃんRPGの村人Aの会話内容

ユニティちゃんRPGの村人Bの会話内容

上のようにあらかじめ会話内容を書いたファイルが出来ました。

会話内容は<>という文字列が登場したら一回で表示する会話が終了するようにしているので途中に<>を入れる必要があります。

ここで注意が必要なのが元のConversationスクリプトのmessageフィールドの名前を変更したりすると、せっかく作成したVillagerAやVillagerBの中身が消えてしまうので注意してください。

これが嫌な人はテキストファイル等に会話内容を保持しておいて読み出すという方法もあります。

Unityにテキストファイルを取り込んでスクリプトから読み込む
Unityにテキストファイルを取り込んでスクリプトから読み込みこんで使用してみます。スクリプト内にテキストをいっぱい書きこむより管理が楽になります。

こっちの方が安全かも・・・・(^_^;)

会話内容は別途パソコンにテキストファイルとして保持したり、紙に残しておいた方が消えた時の悲しみが少なくなるかもしれません・・・・(´Д`)

決してUnity内だけで保持するのはやめましょう。(´Д`)

VillagerScriptスクリプトに追記

村人のスクリプトVillagerScriptにも会話の処理を追記します。

村人にもTalk状態を追加します。

フィールドに会話処理で使うものを追記します。

conversationは先ほど作ったVillagerAやVillagerBファイルをインスペクタで設定します。

conversationPartnerTransformはユニティちゃんのTransformが入ります。

rotationSpeedは会話する時に村人がユニティちゃんの方に向くスピードを設定します。

UpdateメソッドにState.Talk状態の時の処理を追加します。

でユニティちゃんの位置から村人の位置を引いてユニティちゃんの方向を求めたものと村人の前方の角度をVector3.Angleで求め5度より大きい時は村人をユニティちゃんの方向に向かせます。

ユニティちゃんの位置でYだけ村人のYの位置を設定しているのは高さが違う時にYの位置を合わせて計算したい為です。

でQuaternion.Lerpで徐々に現在の角度からユニティちゃんの方向の角度へと変更します。

Quaternion.LookRotationでユニティちゃんの方向のQuaternionを求めています。

SetStateメソッドの第2引数にTransform型の変数を受け取るようにします。

第2引数が指定されていなければnullを設定します。

State.Walk状態に変更する時にnavMeshAgent.isStopped = false;でエージェントの移動を再開させます。

State.Talk状態の時はnavMeshAgent.isStopped = true;でエージェントの移動を止めます。

会話する時はアニメーションをやめさせるためアニメーションパラメータのSpeedを0にしています。

またフィールドのconversationPartnerTransformに引数で受け取ったユニティちゃんのTransofrmを入れて保持します。

VillagerゲームオブジェクトのVillagerScriptの設定は

ユニティちゃんRPGのVillagerScriptの設定

上のようになりました。

これで機能が完成したので、VillagerをCtrl+Dキーを押して複製しVillagerとは少し位置を変えて配置します。

ちなみにここまでのヒエラルキーは

ユニティちゃんのRPGを作ってみよう5の記事までのヒエラルキー全体

上のようになっています。

TalkIconの子要素のBackgroundは現在は削除しております。

Unityを実行して機能を試してみましょう。

上のようになりました。

巡回ポイントが同じなので村人が群がっていますね。

むらびとがむらがっている・・・・(´Д`)

終わりに

いやぁ・・・この会話機能の記事長いですね・・・(^_^;)

この記事からいきなり難しくなってるかも・・・・(´Д`)

だが、本当の闘いはこれからなのであった・・・・・(-_-)

ユニティちゃんライセンス

この作品はユニティちゃんライセンス条項の元に提供されています

コメント

  1. KAGAMI より:

    ConversationScopeScriptですが
    Error CS0117: ‘UnityChanScript’ に ‘State’ の定義がありません と: Error CS0246: 型または名前空間の名前 ‘UnityChanTalkScript’ が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)。 (CS0246)

    何回か見直しましたが以上が出てきます・・・

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