Unityを使った3Dゲームの作り方(かめくめ)Unityを使った3Dゲームの作り方(かめくめ)ゲーム開発エンジンUnityを使った3Dゲームの制作に参考になる情報を公開しています。1今回はユニティちゃんが村人と会話出来る機能を作成していきます。今回の機能はちょっと難しいかも?しれません。前回は村人が巡回ポイントを移動するようにしました。ユニティちゃんのRPGを作ってみよう4ー村人の移動ーユニティちゃんのRPGで村人を配置しナビゲーション機能を使って村の中を歩き回る機能を作成していきます。Unityを使った3Dゲームの作り方(かめくめ)ユニティちゃんの3DRPGを作っていくカテゴリです。gametukurikata.comから見ることが出来ます。村人との会話機能を作成していきます。村人が会話する範囲を作成まずは村人が会話をする範囲を作成していきます。Emptyを選択しSearchAreaという名前にします。Triggerにチェックを入れ衝突をせず検知するようにします。このコライダがユニティちゃんと会話する範囲になります。ColliderのCenterとRadiusを設定しコライダの範囲を調整します。村人の会話が出来る範囲は以下のようにしました。会話範囲に入った時に実行するスクリプト先ほど村人が会話する範囲を作成しましたが、その範囲内に入った時の処理をスクリプトで作成していきます。Scriptを選択し、名前をConversationScopeScriptとし、SearchAreaゲームオブジェクトに取り付けます。ユニティちゃんが遠ざかったら会話相手から外すcol.GetComponent<UnityChanTalkScript>().ResetConversationPartner(transform.parent.gameObject);}}}OnTriggerStayで範囲内にPlayerタグを持ったコライダでそのコライダのUnityChanScriptのGetStateメソッドを呼び出し、ユニティちゃんが会話している時でなければそのコライダからUnityChanTalkScriptのSetConversationPartnerメソッドを呼び出し自身のゲームオブジェクトを渡します。OnTriggerExitでPlayerタグを持つコライダでユニティちゃんの状態が会話状態でない時に範囲外に出たらResetConversationPartnerメソッドに自身のゲームオブジェクトを渡し会話相手から外します。ここでPlayerタグを設定したコライダでユニティちゃんを判定しているので、UnityChanゲームオブジェクトを選択し、インスペクタのTagをPlayerにします。ここでUnityChanScriptのGetStateメソッドを呼び出して状態の判定をしていますが、UnityChanScriptの状態を表す列挙型や状態を取得するGetStateメソッド等は後で作成していきます。UnityChanTalkScriptも後で作成します。会話表示用のUIを作成していきます。ヒエラルキー上で右クリックからUI→Panelを選択し、作成されたCanvasの名前をTalkUIとします。Panelを選択した状態で右クリックからUI→Image、UI→Textを作成します。シーンビューでPanelの四隅の矢印をShiftキーを押しながらドラッグし、会話表示部分の範囲を作成します。上のような感じにしました。stretchにし、Panelのサイズに合わせて伸縮するようにします。rightにし、Panelの右下に表示されるようにします。WidthとHeightは30にします。Resolutionは基準となる画面の解像度でXを1024、Yを768としておきます。ModeはExpandとします。細かいUIの作成方法やこの後作成するユニティちゃんの会話機能はUnityでRPGゲームのメッセージ表示機能を作るUnityでロールプレイングゲームのメッセージ表示機能を作成していきます。19:52の方で解説していますのでそちらを参照してみてください。TalkUIは会話する時だけ見えるようにする為、TalkUIのインスペクタの名前の横のチェックを外し、最初は見えないようにしておきます。次はユニティちゃんが村人と会話が可能である時(村人のSearchAreaのコライダの範囲内にいる時)に表示する会話を促すアイコンのUIを作成します。ヒエラルキー上で右クリックからUI→Panelを選択し、Canvasの名前をTalkIconにします。TalkIconを選択した状態で右クリックからUI→Panelを選択します。centerにし、Widthを200、Heightを70にします。Groupを取り付けます。設定は上のような感じにします。Imageは使用しないので横のチェックを外しておきます。Groupは子要素を横並びに整列させる機能です。Panelの子要素にUI→Imageを作成します。centerにしWidthとHeightを50にします。Imageには押すべきボタンのアイコンを指定します(今回は適当なアイコンを設定しています)。Textのインスペクタは下のようにWidthやHeightを設定し、テキストのサイズと色を変化させています。TalkIconも村人と会話が可能な時だけ見えるようにする為、TalkIconのインスペクタの名前の横のチェックを外し最初は見えないようにしておきます。先ほどConversationScopeScriptでUnityChanTalkScriptのメソッドを呼び出していますのでそのスクリプトを作成していきます。ユニティちゃんの会話処理スクリプトUnityChanTalkScriptをAssets/RPG/Scriptsの中に作成しUnityChanゲームオブジェクトに取り付けます。conversationPartner.GetComponent<VillagerScript>();villagerScript.SetState(VillagerScript.State.Wait);GetComponent<UnityChanScript>().SetState(UnityChanScript.State.Normal);Input.ResetInputAxes();}}conversationPartnerは会話相手を保持して置くフィールド、talkIconやTalkUIは先ほど作ったゲームオブジェクトをインスペクタで設定します。その他フィールドやUpdateメソッドの会話を表示する処理の詳細はUnityでRPGゲームのメッセージ表示機能を作るUnityでロールプレイングゲームのメッセージ表示機能を作成していきます。19:52上の記事で詳しく書いていますので、そちらを参照してください。今回はInput.GetButtonDown(“Jump”)でJumpに割り当てられているボタンを押した時にメッセージの一括表示や次のメッセージの表示をするようにしています。Settings→Inputで設定出来ます。メッセージ表示機能以外の部分を見ていきます。conversationPartner.GetComponent<VillagerScript>();villagerScript.SetState(VillagerScript.State.Wait);GetComponent<UnityChanScript>().SetState(UnityChanScript.State.Normal);}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の設定は上のように設定しました。UnityChanScriptに処理を追加UnityChanScriptに会話している状態を作る為に処理を追加します。ユニティちゃんの状態を表す列挙型Stateを作ります。State{Normal,Talk}ユニティちゃんの状態を保持するstateフィールド、UnityChanTalkScriptを保持するunityChanTalkScriptフィールドを宣言します。GetComponent<UnityChanTalkScript>();}Startメソッドではユニティちゃんの状態の初期化とUnityChanTalkScriptを取得しておきます。次にUpdateメソッド内の処理をユニティちゃんの状態に応じて変化させます。Time.deltaTime);}State.Normal状態の時は今までと同じように移動処理を行い、その中でUnityChanTalkScriptのGetConversationPartnerメソッドで会話相手がいるかどうか調べ、いる時でJumpボタンを押したら状態をState.Talk状態にします。State.Normal状態であろうとState.Talk状態であろうと重力は働かせます。次に状態変更と初期処理を行うSetStateメソッドを追記します。0f);unityChanTalkScript.StartTalking();}}引数で受け取った状態を保持し、ユニティちゃんが会話状態になった時は移動速度velocityを0にし、アニメーションパラメータのSpeedを0にしてアニメーションをIdleにし、unityChanTalkScriptのStartTalkingメソッドを呼び出して会話を始めます。状態を取得するGetStateメソッドを追加します。state;}状態フィールドstateを返しているだけです。村人の会話内容ファイルを作成する村人の会話内容はスクリプト中のstringフィールドで各自保持しておくことも出来ますが、今回はScriptableObjectを使ってあらかじめアセットファイルとして会話内容を作っておき、それを入れ替えるだけにします。ScriptableObjectやあらかじめアセットファイルを作っておく方法はUnityのScriptableObjectを使うUnityのScriptableObjectを使うと、メモリの節約が出来たり、シーン間の移動でデータを共有するのが簡単になります。この記事では基本だけを記述しています。22:32やUnityでScriptableObjectを使ってアイテムデータベースを作成するUnityでScriptableObjectを使ってアイテムデータベースを作成し、そこからアイテム情報を引き出せるようにします。00:16も参照してください。Scriptを選択し、名前をConversationとします。message;}}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メニューのAssetsからCreate→CreateConversationを選択するとConversationファイルを作成できます。どちらかの方法でファイルを作成するとConversationというファイルが出来るので選択した状態でF2キーを押して名前をVillagerAとし、Ctrl+Dキーをおして複製し名前をVillagerBとします。VillagerAとVillagerBのインスペクタでそれぞれ会話内容を記述します。上のようにあらかじめ会話内容を書いたファイルが出来ました。会話内容は<>という文字列が登場したら一回で表示する会話が終了するようにしているので途中に<>を入れる必要があります。ここで注意が必要なのが元のConversationスクリプトのmessageフィールドの名前を変更したりすると、せっかく作成したVillagerAやVillagerBの中身が消えてしまうので注意してください。これが嫌な人はテキストファイル等に会話内容を保持しておいて読み出すという方法もあります。Unityにテキストファイルを取り込んでスクリプトから読み込むUnityにテキストファイルを取り込んでスクリプトから読み込みこんで使用してみます。スクリプト内にテキストをいっぱい書きこむより管理が楽になります。́Д`)決してUnity内だけで保持するのはやめましょう。村人のスクリプトVillagerScriptにも会話の処理を追記します。State{Wait,Walk,Talk}村人にもTalk状態を追加します。フィールドに会話処理で使うものを追記します。2f;conversationは先ほど作ったVillagerAやVillagerBファイルをインスペクタで設定します。conversationPartnerTransformはユニティちゃんのTransformが入ります。rotationSpeedは会話する時に村人がユニティちゃんの方に向くスピードを設定します。UpdateメソッドにState.Talk状態の時の処理を追加します。5fでユニティちゃんの位置から村人の位置を引いてユニティちゃんの方向を求めたものと村人の前方の角度をVector3.Angleで求め5度より大きい時は村人をユニティちゃんの方向に向かせます。ユニティちゃんの位置でYだけ村人のYの位置を設定しているのは高さが違う時にYの位置を合わせて計算したい為です。Time.deltaTime);でQuaternion.Lerpで徐々に現在の角度からユニティちゃんの方向の角度へと変更します。Quaternion.LookRotationでユニティちゃんの方向のQuaternionを求めています。conversation;}SetStateメソッドの第2引数にTransform型の変数を受け取るようにします。第2引数が指定されていなければnullを設定します。false;でエージェントの移動を再開させます。true;でエージェントの移動を止めます。会話する時はアニメーションをやめさせるためアニメーションパラメータのSpeedを0にしています。フィールドのconversationPartnerTransformに引数で受け取ったユニティちゃんのTransofrmを入れて保持します。VillagerゲームオブジェクトのVillagerScriptの設定は上のようになりました。これで機能が完成したので、VillagerをCtrl+Dキーを押して複製しVillagerとは少し位置を変えて配置します。ちなみにここまでのヒエラルキーは上のようになっています。TalkIconの子要素のBackgroundは現在は削除しております。Unityを実行して機能を試してみましょう。上のようになりました。巡回ポイントが同じなので村人が群がっていますね。ディレクティブまたはアセンブリ参照が指定されていることを確認してください)。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。サイト内検索が出来ますプロフィール管理人のかめくめちゃんです。(-_-)メールはこちらにお願いします(記事への質問はコメント欄にお願いいたします)。kamekumechan@gmail.comいずれはSIRENやバイオハザードみたいなアクションゲームを作りたいと思っています。ゲームシナリオが書けないので面白いゲームはなかなか作れません・・・・。(^_^;)名前の由来はカメが好きだからです。Д`)シクシク...お知らせ2020/01/01あけましておめでとうございます。(^^)/ユニティちゃんのRPGを作ってみようのPartyStatusスクリプトでpartyMembersのListの型がCharacterStatusとなっていたのでAllyStatusに変更しました。変更したというか、元々AllyStatusに書き換える前のスクリプトを掲載していたので修正しました。ユニティちゃんのRPGを作ってみよう10ーコマンド画面の作成とステータスの表示ーユニティちゃんのRPGでコマンド画面の作成とステータスコマンドを作成し、選択したキャラクターのステータスを表示するようにしていきます。20:00GetPartyStatusメソッドの戻り値もそれに伴って変更しています。2018/08/07コメント欄へのわたくしの返信は停止しております。わたくしに出来る事は既に記事にしてあるので、ブログ右上の検索窓を活用してください。(._.)またブログの最初の方の機能を積み上げていく記事に関しての疑問点は当ブログ記事のスクリプトの説明と寄せられた質問への回答Unityを使った3Dゲームの作り方(かめくめ)の機能積み上げ形式の記事のスクリプトの説明と寄せられた記事の機能についての質問への回答を掲載しています。21:41も参照してみてください。コメントの返信はありませんが、回答は記事に反映されている可能性があります。当ブログはハイスピードプランです。WordPressの編集画面の動作が早くなった。Unityを使った3Dゲームの作り方(かめくめ).。