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)- 當智能體當前在鏈接上時返回trueint 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