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
- 烘焙 Quantum 導航網格,並通過檢查藍色箭頭的 gizmo 來驗證鏈接(Quantum gizmo 疊加菜單,啟用
NavMeshLinks
並選擇QuantumMapData
遊戲對象) - 代理(Agents)現在會在尋路時考慮該鏈接。
運行時切換導航網格鏈接
可以使用 Quantum 導航網格區域在運行時開啟或關閉鏈接。它們可以烘焙有區域 ID,並且可以全局切換或按智能體切換。更多信息請參閱區域手冊。
簡單區域模式
選擇Unity NavMesh Link
的Area Type
來設置區域。
高級區域模式
- 將Unity
NavMesh Link
的Area Type
設置為區域檢測區域。 - 將
MapNavMeshRegion
腳本附加到UnityNavMesh Link
,設置區域Id
並將Cast Region
設為No Region
。

自定義和信號
可以使用 NavMesh.Links
從導航網格資產中查詢鏈接數據結構。如果需要從鏈接index
到 name
或反之的映射,可以構建一個字典。
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