3

Unity ナビゲーション メッシュ (4 つのプレーン)、ナビゲーション エージェント (球体) をセットアップし、自動および手動のオフ メッシュ リンクをセットアップしました。これでメッシュ間をジャンプするはずです。メッシュ間をジャンプしますが、直線でジャンプします。

言い換えると、エージェントがエッジに到達すると、実際にジャンプするのではなく (オフ メッシュ リンクが描画されるように)、ラインに沿ってまっすぐに移動しますが、速度は少し速くなります。1 つの平面を他の平面よりも高く移動しようとしましたが、球体はまだ直線的にジャンプしていました。

こんなはずじゃないの?カーブでジャンプするようにナビゲーションを設定することはできますか? それとも、自分で実装しようとする必要がありますか?

4

4 に答える 4

13

私はこの質問にたどり着き、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
于 2012-11-09T12:31:32.470 に答える
2

アニメーションで問題を解決することをお勧めします。Jumpオブジェクトのアニメーションを作成し、正しいタイミングで再生するだけです。位置は相対的なので、アニメーションで Y 位置を大きくすると、オブジェクトがジャンプしているように見えます。

これは、兵士が走り回っている Unity サンプルの動作方法でもあります。

于 2012-09-03T12:23:45.957 に答える
0

update() の位置を修正

if (agent.isOnOffMeshLink)
 {
    transform.position =  new Vector3(transform.position.x, 0f, transform.position.z);       
 }
于 2021-02-12T12:28:55.360 に答える