プレイヤーキャラクターをマウスクリックした位置に移動させる
今回は NavMesh 機能の勉強として、マウスクリックでエフェクト表示した場所にプレイヤーキャラクターを移動させる方法を試してみました。
シーンの作成
今回のシーンは Unity公式アセットのモデリングツール ProBuilder を使用し、10m四方で1mの高低差のあるステージを作成しました。
ProBuilder

キャラクターの作成
プレイヤーキャラクターはフリーアセットのキャラクター、Space Robot Kyle を使用します。
キャラクターの制御は Standard Assets の Character アセットをインポートし、ThirdPersonCharacter のコンポーネントを使用します。
まず、メニュー:Assets > Import Package > Charactersを選択。アセットファイルがインポートできたら、[Project]ウィンドウ > Standard Assets > Characters > ThirdPersonCharacter > Prefab > AIThirdPersonController をシーンに配置。
AIThirdPersonController を選択して [Inspector]ウィンドウ > AI Character Control (Script) コンポーネント > 歯車ボタン > Copy Component を選択してコピー。

そして Space Robot Kyle をシーンに配置。 [Inspector]ウィンドウ > Animator コンポーネント > 歯車ボタン > Pastte Component As New を選択。

必要な関連コンポーネントがまとめてペーストされます。

キャラクターのコンポーネント調整
Space Robot Kyle のコンポーネントの設定を行います。
Animator コンポーネントには ThirdPersonAnimatorController を割り当てます。

Cupsule Collider はキャラクターのサイズに合わせて次のように調整。物理マテリアルは ZeroFriction を割り当てます。

Nav Mesh Agent コンポーネントの設定は ThirdPersonCharacter と同じ設定にしました 。

Third Person Character (Script) コンポーネントは Jump Power を 0 に設定。ジャンプポーズのトリガーとなっているGround Check Distance の値を1 にしてジャンプポーズに切り替わらないようにしました。

NavMeshの作成
プレイヤーキャラクターがマウスクリックした位置まで経路探索を行うための NavMesh を作成します。
あらかじめ、[Hierarchy]ウィンドウ > Floor を選択。[Inspector]ウィンドウ > オブジェクト名の右側にある Static チェックボックスにチェックを入れます。

メニュー:Window > AI > Navigation を選択。[Bake]タブを選択して Max Slope とStep Height の値を変更。右下の[Bake]ボタンをクリック。

このように NavMesh が作成されました。

スクリプト作成
次に、マウスクリックした座標にキャラクターが移動する処理のスクリプトを作成します。
キャラクターを制御する方法はUnityの公式ドキュメントで掲載されているNavMeshAgantの使い方 マウスでクリックした位置へエージェントを移動させる – Unity マニュアル と カメラからの Ray – Unity マニュアル を参考にしました。
キャラクターオブジェクト Robot Kyle を選択して [Inspector]ウィンドウ > [Add Component]をクリック > New Script を選択。名前をMoveToClickPoint のスクリプトを作成して割り当てます。
作成したスクリプトは下記の通り。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// AI 関連のライブラリを使用するための宣言
using UnityEngine.AI;
public class MoveToClickPoint : MonoBehaviour
{
// NavMeshAgent コンポーネントを格納する変数
NavMeshAgent agent;
//ゲーム開始時の処理
void Start()
{
// 変数 agemt に NavMeshAgent コンポーネントを格納する
agent = GetComponent<NavMeshAgent>();
}
//ゲーム実行中の処理
void Update()
{
// マウス左クリックされたとき
if (Input.GetMouseButtonDown(0))
{
// カメラから発射したレイが衝突したオブジェクトを格納する変数 hit を宣言
RaycastHit hit;
// カメラからマウスでクリックした方向にレイを発射して ray に格納
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// もし発射したレイがコライダーと衝突したら(衝突検知最大距離 100)
if (Physics.Raycast(ray, out hit, 100))
{
// 変数 hit の座標を NavMeshAgent の目標点に渡す
agent.destination = hit.point;
}
}
}
}
シーンを再生して動作確認。ちゃんとマウスクリックした場所にキャラクターが移動します。

マウスクリックした位置にエフェクトを表示する
キャラクターの目標位置がクリックしただけだと視覚的に分かりにくいので、エフェクトを表示してみます。
こちらのページ 【Unity】タップした位置にエフェクトを表示する – テラシュールブログ を参考にさせていただきました。
パーティクルを発生させるオブジェクトを作成
[Hierarchy]ウィンドウ > [Create]ボタン > Create Empty を選択して空オブジェクトを作成。名前をClick Point に変更します。 [Inspector]ウィンドウ > [Add Component]をクリック > Particle Systemを選択。コンポーネントの基本パラメータはは下記のように設定しました。
さらに Size Over Lifetime のパラメータを追加してサイズを調整。

そして Renderer のパラメータは 標準のパーティクルテクスチャを使用し、 水平のビルボードに設定、パーティクルがステージオブジェクトと干渉しないように基点Y座標を調整しました。

スクリプトの修正
先に作成したスクリプト MoveToClickPoint にパーティクルを発生させるコードを追加します。マーカー部分が追加したコードです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// AI 関連のライブラリを使用するための宣言
using UnityEngine.AI;
public class MoveToClickPoint : MonoBehaviour
{
// NavMeshAgent コンポーネントを格納する変数
NavMeshAgent agent;
// パーティクルコンポーネントを格納する変数
public ParticleSystem clickEffect;
//ゲーム開始時の処理
void Start()
{
// 変数 agemt に NavMeshAgent コンポーネントを格納する
agent = GetComponent<NavMeshAgent>();
}
//ゲーム実行中の処理
void Update()
{
// マウス左クリックされたとき
if (Input.GetMouseButtonDown(0))
{
// カメラから発射したレイが衝突したオブジェクトを格納する変数 hit を宣言
RaycastHit hit;
// カメラからマウスでクリックした方向にレイを発射して ray に格納
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// もし発射したレイがコライダーと衝突したら(衝突検知最大距離 100)
if (Physics.Raycast(ray, out hit, 100))
{
// 変数 hit の座標を NavMeshAgent の目標点に渡す
agent.destination = hit.point;
// 変数 hit の座標を パーティクルコンポーネントの座標に渡す
clickEffect.transform.position = hit.point;
// パーティクルを発生させる
clickEffect.Emit(1);
}
}
}
}
スクリプトを保存したら Move To Click Point (Script) コンポーネントの clickEffect フィールドに パーティクルを発生させるオブジェクト Click Point を割り当てます。

WebGLサンプル
ここまでの内容を動作確認して WebGLでビルドしてみました。マウスクリックするとクリックした場所にパーティクルが発生し、キャラクターが移動します。
画像クリックで再生(ファイルサイズ:約14MB)