私はこの質問にたどり着き、Unity サンプルを掘り下げる必要がありました。重要なビットを抽出することで、人々にとって簡単になることを願っています。
独自のアニメーション/トランジションを navmesh リンクに適用するには、すべての offmesh リンク トラバーサルを処理することを Unity に伝え、エージェントが offmesh リンク上にあるかどうかを定期的にチェックするコードを追加する必要があります。最後に、移行が完了したら、エージェントを移動したことを Unity に伝え、通常の navmesh の動作を再開する必要があります。
リンク ロジックの処理方法はユーザー次第です。直線的に進むことも、ワームホールを回転させることもできます。ジャンプの場合、unity はアニメーションの進行状況を lerp 引数として使用してリンクをトラバースします。これは非常にうまく機能します。(ループやより複雑なアニメーションを実行している場合、これはうまく機能しません)
重要な単位ビットは次のとおりです。
_navAgent.autoTraverseOffMeshLink = false; //in Start()
_navAgent.currentOffMeshLinkData; //the link data - this contains start and end points, etc
_navAgent.CompleteOffMeshLink(); //Tell unity we have traversed the link (do this when you've moved the transform to the end point)
_navAgent.Resume(); //Resume normal navmesh behaviour
今簡単なジャンプのサンプル...
using UnityEngine;
[RequireComponent(typeof(NavMeshAgent))]
public class NavMeshAnimator : MonoBehaviour
{
private NavMeshAgent _navAgent;
private bool _traversingLink;
private OffMeshLinkData _currLink;
void Start()
{
// Cache the nav agent and tell unity we will handle link traversal
_navAgent = GetComponent<NavMeshAgent>();
_navAgent.autoTraverseOffMeshLink = false;
}
void Update()
{
//don't do anything if the navagent is disabled
if (!_navAgent.enabled) return;
if (_navAgent.isOnOffMeshLink)
{
if (!_traversingLink)
{
//This is done only once. The animation's progress will determine link traversal.
animation.CrossFade("Jump", 0.1f, PlayMode.StopAll);
//cache current link
_currLink = _navAgent.currentOffMeshLinkData;
//start traversing
_traversingLink = true;
}
//lerp from link start to link end in time to animation
var tlerp = animation["Jump"].normalizedTime;
//straight line from startlink to endlink
var newPos = Vector3.Lerp(_currLink.startPos, _currLink.endPos, tlerp);
//add the 'hop'
newPos.y += 2f * Mathf.Sin(Mathf.PI * tlerp);
//Update transform position
transform.position = newPos;
// when the animation is stopped, we've reached the other side. Don't use looping animations with this control setup
if (!animation.isPlaying)
{
//make sure the player is right on the end link
transform.position = _currLink.endPos;
//internal logic reset
_traversingLink = false;
//Tell unity we have traversed the link
_navAgent.CompleteOffMeshLink();
//Resume normal navmesh behaviour
_navAgent.Resume();
}
}
else
{
//...update walk/idle animations appropriately ...etc