ユニティちゃんのRPGを作ってみよう4ー村人の移動ー

今回は村の中に村人を配置し、村の中を移動をする機能を作成していきたいと思います。

前回は村を作成しました。

ユニティちゃんのRPGを作ってみよう3ー村の作成ー
ユニティちゃんのRPGでTerrainを使って村の作成をしていきます。

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

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

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

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

村人用のキャラクターを配置する

まずは村人に使用する3Dキャラクターを用意します。

Ctrl+9キーを押してAsset Storeウインドウを開きカテゴリの3D、キャラクター、ヒューマノイドにチェックを入れ、価格で無料アセットにチェックを入れます。

出てきたCharacter Elfを今回は村人の3Dモデルとして使用します。

Villageゲームオブジェクトを選択した状態で右クリックからCreate Emptyを選択し、名前をVillagersとします。

TransformのPosition、RotationのXYZは全て0にしておきます。

Villagersを選択した状態で右クリックからCreate Emptyを選択し、名前をVillagerとします。

VillagerのPosition、RotationのXYZも全て0にしておきます。

Villager以下が一人の村人を表していて、その子要素のモデルを変更するだけで他の村人を作成することが出来るようにしていきます。

Assets/Character_Elf/Mesh/Elf_MeshをVillagerにドラッグ&ドロップし子要素にします。

Elf_Meshを選択した状態でF2キーを押し名前をElfにします。

Elfを選択した状態で右クリックからUnpack Prefab Completelyを選択しプレハブとのリンクを解除します。

ヒエラルキーに配置したElfのマテリアルはデフォルトのマテリアルになっているので変更します。

Elfの子要素のBody_Meshを選択し、インスペクタのMaterialsのElement0にAssets/Character_Elf/MaterialsにあるCharacter_Elfマテリアルを設定します。

現在までの階層は

ユニティちゃんRPGのVillageの階層

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

Animator Controllerの取り付け

Elfゲームオブジェクトを選択し、インスペクタのAdd ComponentからMiscellaneous→Animatorを選択し取り付け、Apply Root Motionのチェックを外します。

Assets/RPG/Animatorsフォルダに移動し、右クリックからCreate→Animator Controllerを選択し、名前をElfとします。

ElfのAnimator Controllerを選択した状態でAnimatorウインドウを見て、Idle状態、Walk状態を作成し、それぞれ遷移するようにします。

Idle状態にはスタンダードアセットのHumanoidIdle、Walk状態にはスタンダードアセットのHumanoidWalkのアニメーションを設定します。

作り方はユニティちゃんのAnimator Controllerを作った時と同じなので割愛します。(-_-)

アニメーションパラメータにFloat型のSpeedを作成します。

ユニティちゃんRPGの村人のAnimator Controller

Idle→WalkはHas Exit Timeのチェックを外しSpeedがGreaterで0.1
Walk→IdleはHas Exit Timeのチェックを外しSpeedがLessで0.1

という条件にします。

村人の移動機能

村人を動かす場合は村の中のいくつかのポイントを自動巡回するような感じにしたいです。

その為、CharacterControllerの移動機能を使って移動させると歩いている途中に壁があっても目的地にただ移動するだけなので、壁を回避させるスクリプトを追加しない限り壁にぶつかってしまいます。

そこで今回はNavigation機能を使って村人が指定した巡回ポイントを周るようにしていきます。

Navigation機能については

敵キャラをUnityのナビゲーション機能を使って移動させる
Unityのナビゲーション機能を使って敵キャラクターを移動させます。ナビゲーション機能はあらかじめBakeされたフィールドを移動出来る機能です。

Unityのナビゲーション機能を使って決まった場所を巡回させる
Unityのナビゲーション機能を使って決まった場所を巡回させる機能を作成していきます。

も参照してみてください。

村人の移動出来る場所をBakeする

まずは村人が移動出来る場所を設定します。

UnityのメニューのWindowからAI→Navigationを選択します。

VillageGroundゲームオブジェクトのインスペクタで名前の横のStaticにチェックが入っているのを確認したらNavigationウインドウを見ます。

Bakeタブを押してエージェント(NavMesh上を動くキャラクター)の移動条件を設定します。

ユニティちゃんRPGの村のNavMeshBakeの設定

上のような感じで設定しました。

設定が出来たら下のBakeボタンを押してNavMeshをベイクします。

ベイクが終わると、VillageGroundの地形上でエージェントが移動できる場所が色分けされます。

ユニティちゃんRPGの村のNavMeshBake

村人にNavMeshAgentを取り付け巡回させる

村人にNavMeshAgentコンポーネントを取り付けてNavMesh上を動くようにします。

Villagerゲームオブジェクトを選択し、インスペクタのAdd ComponentからNavigation→NavMeshAgentを選択し取り付けます。

NavMeshAgentの最大移動速度であるSpeedを1.3にし、Radiusに0.3とHeightに1.8を指定して障害物を避ける半径と高さを指定します。

Villagerに取り付けたNavMeshAgentの設定

これでVillagerにはNavMesh上を移動出来る移動機能が取り付けられました。

巡回ポイントの作成

村人が巡回するポイントを作成していきます。

Villageゲームオブジェクトを選択した状態で右クリックからCreate Emptyを選択し名前をPatrolPointsParentとし、インスペクタでTransform、RotationのXYZを全て0にします。

PatrolPointsParentを選択した状態で右クリックからCreate Emptyを選択し、名前をPoint0とし、シーンビューで巡回する位置に移動させます。

Point0を選択しCtrl+Dキーを押して複製し、名前をPoint1にし次の巡回する位置に移動させます。

同じように複数の巡回ポイントを作ります。

ユニティちゃんRPGの村人の巡回ポイント

Point0~Point5までをCtrlキーを押しながら全て選択し、インスペクタの名前の横のアイコンを変更します。

シーンビュー上でゲームオブジェクトの位置をわかりやすくする

するとシーンビュー上でPoint0~Point5までのゲームオブジェクトの位置がアイコンで表示されてわかりやすくなります。

ユニティちゃんRPGの村人の巡回ポイントがアイコンで表示された

巡回ポイントを周るスクリプトの作成

Villagerには移動機能が取り付けられたので、後はその機能をスクリプトから操作し移動させます。

Assets/RPG/Scriptsフォルダ内にVillagerScriptを作成しVillagerゲームオブジェクトに取り付けます。

インスペクタでpatrolPointsParentにヒエラルキーのPatrolPointsParentゲームオブジェクトをドラッグ&ドロップして設定すると、patrolPoints配列はPatrolPointsParentの子要素分の要素を確保して入れます。

Updateメソッドでは村人の状態に合わせて処理を分けていて、State.Walk状態の時はアニメーションパラメータSpeedにエージェントの潜在的なスピードを渡しています。

navMeshAgent.remainingDistanceで目的地とエージェントの距離を計算出来るので、距離が十分近くなったらSetStateメソッドを呼び出して村人の状態をState.Wait状態に変更します。

State.Wait状態だった時はその場で一定時間待たせる為に時間を計測し、時間がwaitTimeを越えたらState.Walk状態へと変更し次の巡回ポイントに移動させます。

時間の計測は

で行っていてelapsedTimeには経過時間を足していきますが、Time.deltaTimeは前回のUpdateメソッドが呼ばれてからの経過時間なので、Updateメソッドが呼ばれるごとにTime.deltaTimeを足していくと今までの経過時間が計算されるという仕組みです。

SetStateメソッドでは引数で変更する状態を受け取り、その状態に応じて初期設定と村人の状態を変更する処理をしています。

NavMeshAgentの目的地を設定しているのは、

上の部分でGetDestinationで目的地であるVector3の値を得て、それをnavMeshAgent.SetDestinationメソッドの引数として渡します。

navMeshAgent.SetDestinationは引数で与えられた位置に目的地を設定し、移動を開始させます。

SetNextPositionメソッドは次の巡回ポイントを目的地に設定するメソッドで、SetDestinationは引数で受け取った位置を目的地にするメソッド、GetDestinationは現在の目的地を返すメソッドになります。

ユニティちゃんとの衝突

これでUnityを実行して動かすと村人であるエルフが巡回ポイントを順番に周っていきます。

しかしユニティちゃんをすり抜けてしまいます。

これはユニティちゃんは移動するのであらかじめベイクされたNavMesh上を動くだけの村人には無視されてしまうからです。

そこでユニティちゃんが村人に障害物として認識してもらえるようにします。

UnityChanゲームオブジェクトを選択しインスペクタのAdd CompoenntからNavigation→Nav Mesh Obstacleを取り付けます。

Nav Mesh Obstacleの設定で障害物として認識させる範囲をCharacterControllerのコライダのサイズと合わせます(合わせなくても避ける範囲を指定してください)。

ユニティちゃんに取り付けたNavMeshObstacleの設定

NavMeshObstacleを取り付けるとNavMeshAgentを持つキャラクターがその部分を避けて通るようになります。

これで村人はユニティちゃんを避けて通るようになりましたが、ユニティちゃんが村人に衝突しようとすると村人をすり抜けてしまいます。

そこで村人にCapsule Colliderを取り付け衝突するようにします。

Villagerを選択し、インスペクタのAdd ComponentからPhysics→Capsule Colliderを選択し、コライダの範囲を調整します。

ユニティちゃんRPGの村人の衝突用コライダ

これでユニティちゃんが村人と衝突するようになりました。

Unityを実行して確認してみましょう。

上のようになりました。

終わりに

今回は村人をナビゲーション機能を使って村を巡回させる機能を作成しました。

村人といってもまだ一人しかいませんが・・・・、次回の会話機能が完成したらあと一人追加してみようかと思います。

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

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

コメント

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