前回記事の続きです。
bluebirdofoz.hatenablog.com
本記事は以下の記事を参考に作業を実施します。
tarukosu.hatenablog.com
「SDユニティちゃんを歩かせてみる」の項目からの実施になります。
まずは利用規約を確認し、以下のSDユニティちゃんデータを取得します。
・SDユニティちゃん 3Dモデルデータ
http://unity-chan.com/download/releaseNote.php?id=SDUnityChan
前回作成したプロジェクトを改めて開きます。
ダウンロードした SD_UnityChan パッケージをプロジェクトに取り込みます。
Assets/UnityChan/SD_unitychan/Prefabs 配下から SD_unitychan_humanoid.prefab をシーンに追加します。
次に SD_unitychan_humanoiod オブジェクトのコンポーネントを以下の通り、設定します。
1.調整した Agent の大きさに合うようスケールを全て 0.3 に設定する。
2.SD_unitychan_humanoid にアタッチされている Script について全て無効化する。
3.NavMeshAgent のコンポーネントをアタッチする。
NavMeshAgent の Speed や Obstacle は参考記事を元に値を調整しています。
Agent の希望する移動速度やモデルの大きさに合わせて設定するようです。
次に SD_unitychan_humanoid の移動モーションを設定します。参考記事にある通り、下記を参照します。
tsubakit1.hateblo.jp
最初に Animator コンポーネントにある ApplyRootMotion のチェックを外します。
これでキャラクタの移動は NavMeshAgent または Scriptでしか動かなくなります。
Assets で右クリック -> Create -> AnimatorController で新しいアニメーションコントローラを作成します。
作成した Animator を開いたら Float 型の Speed パラメータを追加します。
モーションの設定として「ブレンドツリー」の機能を使います。
Animator ビュー上で右クリック -> CreateState -> FromNewBlendTree で「ブレンドツリー」の State が作成できます。
作成された BlendTree を選択し、Motion に設定されている BlendTree をダブルクリックします。
すると BlendTree の Inspector タブが表示されます。
まず Motion の「+」ボタンを押下して AddMotionField を選択し、3つのモーションを追加します。
次に AutomateThresholds のチェックを外します。
すると、閾値の設定が手動で行えるようになるので、Motion と Threshold を以下の通り設定します。
ちなみにモーション選択の際、SDユニティちゃんをそのままインポートしていると、それぞれ同名の2種類のモーションがあります。
このとき、~_humanoid というファイル名になっている方のモーションを選択するようにします。
以上でアニメーションコントローラの作成は完了です。
SD_unitychan_humanoid オブジェクトの Animator にコントローラを設定します。
移動中に Speed パラメータを操作してモーションを再生するスクリプトを用意します。
参考記事の unitychanAnimation.cs スクリプトを作成し、SD_unitychan_humanoid オブジェクトに追加します。
最後にタップ位置まで移動するスクリプトを用意します。
以下の手順で MoveToClickPoint オブジェクトを作成します。
1.空オブジェクトの MoveToClickPoint オブジェクトを作成する。
2.参考記事の MoveToClickPoint.cs スクリプトを作成し、MoveToClickPoint オブジェクトに追加する。
3.MoveToClickPoint.cs スクリプトの Agent に SD_unitychan_humanoid オブジェクトを設定する。
4.MoveToClickPoint オブジェクトに LineRenderer コンポーネントを追加する。
unity 上で動作確認を行うため、MoveToClickPoint.cs について以下のコードを追加しました。
・MoveToClickPoint.cs
void Update()
{
if (Input.anyKeyDown)
{
Debug.Log("click LOG");
if (GazeManager.Instance.IsGazingAtObject)
{
var hitInfo = GazeManager.Instance.HitInfo;
if (!Agent.gameObject.activeSelf)
{
Agent.gameObject.SetActive(true);
Agent.transform.position = hitInfo.point;
}
else
{
Agent.destination = hitInfo.point;
var path = new NavMeshPath();
NavMesh.CalculatePath(Agent.transform.position, Agent.destination, NavMesh.AllAreas, path);
var positions = path.corners;
lineRenderer.widthMultiplier = 0.1f;
lineRenderer.positionCount = positions.Length;
for (int i = 0; i < positions.Length; i++)
{
Debug.Log("point " + i + "=" + positions[i]);
lineRenderer.SetPosition(i, positions[i]);
}
}
}
}
}
シーンを再生して、移動先に視点を合わせてマウスクリックを行うと……。
SDユニティちゃんが NavMesh の移動可能範囲に沿ってルートを自動生成して歩きました。成功です。
こんなに簡単に動的な経路探索のロジックが利用できるとは驚きです。
次回は経路探索のロジックを応用して、現在位置から目的地の道筋を表示する機能を試してみます。
bluebirdofoz.hatenablog.com