This document is about: QUANTUM 3
SWITCH TO

Using Navmesh Off Mesh Links

Unity 的 Nav Mesh Links腳本會被烘焙到 Quantum 導航網格中 (Quantum.NavMesh.Links)。

烘焙過程中會使用以下字段:

  • Bidirectional - 創建兩個方向相反的鏈接
  • CostModifier - 用作Quantum.NavMeshLink.CostOverride的輸入
  • Area Type - 設置鏈接的區域(參見「運行時切換導航網格鏈接」部分)
  • Activated - 若未激活,烘焙時會跳過該鏈接
  • GameObject.name - 用作 Quantum 的 Quantum.NavMeshLink.Name的輸入

創建導航網格鏈接

  • 創建並配置 Unity 的NavMesh Link
    Off Mesh Link Setup
  • 烘焙 Quantum 導航網格,並通過檢查藍色箭頭的 gizmo 來驗證鏈接(Quantum gizmo 疊加菜單,啟用NavMeshLinks並選擇QuantumMapData遊戲對象)
    Nav Mesh Link Gizmo
  • 代理(Agents)現在會在尋路時考慮該鏈接。
    Nav Mesh Link Path

運行時切換導航網格鏈接

可以使用 Quantum 導航網格區域在運行時開啟或關閉鏈接。它們可以烘焙有區域 ID,並且可以全局切換或按智能體切換。更多信息請參閱區域手冊

簡單區域模式

選擇Unity NavMesh LinkArea Type來設置區域。

高級區域模式

  • 將Unity NavMesh LinkArea Type設置為區域檢測區域。
  • MapNavMeshRegion腳本附加到Unity NavMesh Link,設置區域Id並將Cast Region設為No Region
Off Mesh Link Regions

自定義和信號

可以使用 NavMesh.Links從導航網格資產中查詢鏈接數據結構。如果需要從鏈接indexname或反之的映射,可以構建一個字典。

NavMeshPathfinder組件具有以下鏈接 API:

  • bool IsOnLink(FrameBase) - 當智能體當前在鏈接上時返回true
  • int CurrentLink(FrameBase) - 返回指向NavMesh.Links的當前鏈接索引,若當前不在鏈接上則返回-1

路點(Waypoint)具有與鏈接相關的WaypointFlags:

  • LinkStart - 此路點是鏈接的起點
  • LinkStop - 此路點是鏈接的終點
  • RepathWhenReached - 到達此路點後,智能體重新執行尋路

當智能體在鏈接上時設置新目標,智能體會先完成當前鏈接,再執行尋路(參見 WaypointFlag.RepathWhenReached)。

只要智能體正在穿越鏈接,就不會執行自動重新尋路(例如 NavMeshAgentConfig.MaxRepathTimeout)。

默認情況下,智能體會以正常速度穿越鏈接。

要在到達鏈接時控制智能體移動,可以使用ISignalOnNavMeshWaypointReached信號。此後,可以在動畫完成前禁用智能體,或者在後續的 ISignalOnNavMeshMoveAgent回調中覆蓋移動。

  • 接收任何導航回調需要啟用 SimulationConfig.Navigation.EnabledNavigationCallbacks
  • 接收ISignalOnNavMeshMoveAgent回調需要將 NavMeshAgentConfig.MovementType設置為Callback,可以在運行時更改智能體的配置。

以下示例代碼在智能體踏上鏈接起點路點時執行瞬移。

C#

namespace Quantum
{
  using Photon.Deterministic;
  using UnityEngine.Scripting;

  [Preserve]
  public unsafe class NewQuantumSystem : SystemMainThread, ISignalOnNavMeshWaypointReached
  {
    public override void Update(Frame frame)
    {
    }

    public void OnNavMeshWaypointReached(Frame frame, EntityRef entity, FPVector3 waypoint, Navigation.WaypointFlag waypointFlags, ref bool resetAgent)
    {
      var agent = frame.Get<NavMeshPathfinder>(entity);
      var waypointIndex = agent.WaypointIndex;
      if ((waypointFlags & Navigation.WaypointFlag.LinkStart) == Navigation.WaypointFlag.LinkStart)
      {
        // There always is another waypoint after the LinkStart
        var linkDestination = agent.GetWaypoint(frame, waypointIndex + 1);
        f.Unsafe.GetPointer<Transform2D>(entity)->Position = linkDestination.XZ;
      }
    }
  }
}
Back to top