パス フォローイングをモニタする

Gameware Navigation パス フォローイング システムは、キャラクタがいつパス フォローイングを停止するか、またはキャラクタがターゲットへの新しいパスをいつ計算する必要があるかについて、高レベルの決定を行いません。このレベルの決定はユーザが行う必要があります。パスに追従するように Bot に要求すると、停止するように指示するか、別のパスに追従するように指示するまで追従しようとします。

ただし、パス フォローイング システムの現在の状態は読み取り用に常に開かれているため、キャラクタがパスに追従中に発生する状況またはイベントに対応することができます。対応するイベント、イベントをチェックする頻度(すべてのフレーム、特定の時間間隔で定期的に、など)、およびそれに応じて実行するアクションを自由に決定することができます。

このページではイベントに対応するための最も一般的な方法のいくつかを説明します。

PathEvent を対話形式で操作する

PathEvent システムは、キャラクタのパスを監視し、そのパスに影響を与える NavData の動的な変更に対応するために Gameware Navigation パス フォローイング システムが提供する主な機能の 1 つです。このシステムの仕組みと使用方法の詳細については、「PathEvent を監視する」を参照してください。

パス フォローイングのための BotOutput にアクセスする

Bot::GetBotOutput() 関数を使用してパス フォローイングのための Bot 出力(outputVelocityoutputFrontDirectionavoidanceResultUpperBoundType)を読み込むことや、IsPathRecomputationNeeded() 関数にアクセスすることができます。

パスが無効な場合(UpperBoundType_PathInvalid)や、パスの値がない場合(UpperBoundType_NoPath)には、UpperBoundType は特定の値となります。この場合、GetUpperBound() はパス上の無効な位置を返します。

Trajectory がパスに追従できるかどうかテストする

Trajectory オブジェクトがそれ以上パスに追従できない場合、IsPathRecomputationNeeded() は true を返します。この場合、パス フォローイングのために Trajectory オブジェクトを使用している Bot は行き詰ってしまい、この問題を解決するには、新しいパスを計算する必要があります。

if (navBot->GetBotOutput().IsPathRecomputationNeeded())
    navBot->ComputeNewPathToDestination(destination);

到着をテストする

キャラクタがターゲット地点に到着したときは、通常、不要な計算を回避するためにパス フォローイング システムを停止します。ターゲットへの到着をチェックするには、多くの方法があります。簡単な方法の 1 つは、指定された半径を使用してジオメトリのテストを実行する Bot::HasReachedPosition() メソッドを呼び出す方法です。

例: [Tutorial_FirstIntegration.cpp からのコード]

bool MyGameEntity::HasArrived()
{    
    KyFloat32 arrivalPrecisionRadius = m_navBot->GetConfig().m_pathProgressConfig.m_checkPointRadius;
    if (m_navBot->HasReachedPosition(m_destinationPosition, arrivalPrecisionRadius))
    {
        return true;
    }

    return false;
}

キャラクタが到着したら、Bot::ClearFollowedPath() を呼び出すことによってパス フォローイングをキャンセルすることができます。

パス計算の成功をテストする

パス フォローイング システムによって計算された速度を取得してキャラクタに適用する前に、パス ファインディング システムがパスの検索に成功したかをチェックする場合があります。Bot::GetFollowedPath() を呼び出してください。このメソッドが KY_NULL を返す場合は、静的パスの計算に成功していないか、計算が進行中です。

例:

    if (m_navBot->GetFollowedPath() == KY_NULL)
        m_velocity = Kaim::Vec3f::Zero();
    else
        m_velocity = m_navBot->GetBotOutput().m_outputVelocity;

パスの計算に成功しない場合は、パス ファインディング クエリのステータスの値を取得することにより、詳細な情報を取得することができます。たとえば、AStarQuery を使用する場合、AStarQuery::GetResult() を呼び出すことができます。

使用するクエリのタイプに関係なく、次のメソッドを呼び出すことで処理のステータスと結果に関する情報を取得できます。

m_navBot->GetPathFinderQuery()->m_processStatus;
m_navBot->GetPathFinderQuery()->GetPathFinderResult();

パス全体の有効性をテストする

Bot がパスに追従中にパスを横切る形で NavData が変更されると、ターゲットへのルート全体が塞がれ、Bot のターゲット地点への移動がすぐに停止しない場合があります。たとえば、動的な障害または禁止された TagVolume によりキャラクタがまだ到達していない通路が塞がれる場合があります。上記の説明に従ってターゲット ポイントのステータスをテストしている限り、キャラクタが塞がれた地形に到達し、LivePath 沿いにターゲットまでの有効なポイントを見つけられない場合、パスを再計算します。しかし、塞がれたパスに対してより早く対応する必要がある場合もあります。

目的地までのパス全体が有効かどうかをテストするには、Bot::GetBotOutput().GetUpperBoundType() の結果を確認します。この結果について次の表で説明します。

結果 説明
UpperBoundType_NoPath パスがなく、有効な UpperBound がありません。
UpperBoundType_PathInvalid パス全体が無効で、有効な UpperBound がありません。
UpperBoundType_Temporary パスが検証中のため、現在最後まで追従することができません。UpperBound は一時的な限界を提供しますが、これはパスが無効であることを意味することにはなりません。次のフレームでさらに評価されます。
UpperBoundType_PathLastNode UpperBound がパスの最後のノードであり、最後まで追従できます。
UpperBoundType_ValidityUpperBound パスの最後まで追従することができません。UpperBound がパスに沿った上限であり、これは最後のノードではありません。この場合、現在のパスへの追従を停止してパスの再計算を試してみてください。あるいは、キャラクタが UpperBound 位置の一定の半径内に到達して地形が塞がれていることを確認するまでキャラクタに現在のパスに追従させるなどの方法で、キャラクタの地形についての限られた情報をシミュレートした方がいいかもしれません。