テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】NavMeshとRigidbodyを連携して動かす

f:id:tsubaki_t1:20161110232057g:plain

今回はNavmeshで動かすキャラクターを一時的に物理演算で動かしてみます。

UnityのNavmesh(経路探索AI)はNavmeshAgentというPhysicsとは異なった力によって動きます。その為、PhysicsとNavmeshを連携させる場合、少々面倒な事になります。

 

まず理解する必要があるのが、NavmeshはTransform移動もしくはRigidbodyによる移動とは異なる座標を持っているという面倒くさい事実です。

このため、Navmeshの座標を移動させる場合は、単純にtransform.positionを移動させるだけでは不十分です。

下のGifアニメでは、本来通れないハズの崖下から崖上へのルートを通過してしまっています。

f:id:tsubaki_t1:20161110222327g:plain

 

この問題を解決するには、Navmesh的に座標を更新する必要があります。transform.positionではなくNavmeshAgent.Warpです。

これなら、下のように崖を登る事無くちゃんと移動してくれます。

f:id:tsubaki_t1:20161110222920g:plain

 

但しNavmeshAgent.WarpはNavmesh上の座標でないと"SetDestination" can only be called on an active agent that has been placed on a NavMesh.というエラーが出ます。もしNavmeshと少し外れた位置に着地するような場合、NavMesh.SamplePositionで座標の補正を行うと良いです。

 

次に、マウスを押してる時に持ち上げ離すと物理演算に従って落下、着地後にNavmesh再開を行います。

持ち上げはRaycastで当たった位置の上にでもtransformを持っていけば良いので、落下部分です。この部分は単純にRigidbodyのIsKinematicをfalseにしつつNavmeshAgent.Stopを呼べば良いです。この時、NavmeshAgent.updatePositionをfalseにしないと一瞬で地面に到着してしまうので注意が必要です。

f:id:tsubaki_t1:20161110234027g:plain

 

後は着地した後Navmeshによる移動を再開します。再開時にはNavmeshAgent.updatePositionをtrueにしたりRigidbody.isKinematicをtrueにするのを忘れずに。

gist.github.com

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp