Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

2D 導覽總覽

Godot 提供多種物件、類別與伺服器,協助 2D 與 3D 遊戲實作基於格狀或網格的導覽與尋路。以下將快速總覽 Godot 中所有 2D 場景可用的導覽相關物件及其主要用途。

Godot 提供以下物件與類別以支援 2D 導覽:

  • Astar2D

    Astar2D 物件可在具有權重的**點**構成的圖中尋找最短路徑。

    AStar2D 類別最適合用於格狀(儲存格)為基礎的 2D 遊戲,不需角色到達區域中任意位置,而僅需到達預先定義的特定位置。

  • AstarGrid2D

    AstarGrid2D 是 AStar2D 的變體,專為部分 2D 格狀結構(Grid)設計。

    AstarGrid2D 在適用時更容易使用,因為不用手動建立點並將它們連接起來。

  • NavigationServer2D

    NavigationServer2D 提供強大的伺服器 API,可在由導覽網格定義的區域中尋找兩個位置間的最短路徑。

    NavigationServer 最適合用於需讓角色移動至導覽網格區域內任意位置的 2D 即時遊戲。網格(Mesh)導覽適用於大型遊戲世界,因為一大片區域常可僅用單一多邊形定義,若用格子則需許多儲存格。

    NavigationServer 會管理多個導覽地圖,每張地圖由數個包含導覽網格資料的區域組成。代理可被放置於地圖上進行避障計算。與伺服器溝通時,會以 RID 來引用內部地圖、區域與代理。

    可用的 NavigationServer RID 型別如下。
    • 導覽地圖 RID

      引用特定的導覽地圖,地圖中包含區域與代理。地圖會根據區域間距離自動合併導覽網格,並於每個物理影格同步區域與代理。

    • 導覽區域 RID

      引用特定導覽區域,該區域可存放導覽網格資料。可啟用或停用區域,並可用導覽層(navigation layer)位元遮罩限制其用途。

    • 導覽連結 RID

      引用特定導覽連結,可連接導覽網格上兩個任意距離的位置。

    • 導覽代理 RID

      引用特定避障代理。避障效果可透過半徑值設定。

    • 導覽障礙 RID

      引用特定避障障礙,可用來影響及限制代理的避障速度。

以下場景樹節點可作為輔助元件,協助操作 NavigationServer2D API。

  • NavigationRegion2D 節點

    此節點持有 NavigationPolygon 資源,定義供 NavigationServer2D 使用的導覽網格。

    • 區域可設為啟用或停用。

    • 可透過 navigation_layers 位元遮罩進一步限制其在尋路時的用途。

    • NavigationServer2D 會根據區塊間的距離,自動將不同區塊的導覽網格合併為一個整體導覽網格。

  • NavigationLink2D 節點

    此節點可連接導覽網格上兩個任意距離的位置,供尋路使用。

    • 連結可設為啟用或停用。

    • 連結可設為單向或雙向。

    • 可透過 navigation_layers 位元遮罩進一步限制其在尋路時的用途。

    連結會告知尋路系統有此連接,並指定其消耗。實際的代理控制與移動需於自訂腳本處理。

  • NavigationAgent2D 節點

    此輔助節點可簡化常用的 NavigationServer2D 尋路與避障 API 呼叫。請將本節點作為 Node2D 派生節點的子節點使用。

  • NavigationObstacle2D 節點

    此節點可用來影響及限制啟用避障功能的代理的避障速度。注意:此節點**不會**影響代理的尋路,若要改變尋路必須修改導覽網格。

2D 導覽網格由下列資源定義:

  • NavigationPolygon 資源

    存放 2D 導覽網格資料的資源。提供多邊形繪製工具,可於編輯器內或執行時定義導覽區域。

    • NavigationRegion2D 節點會使用該資源來定義其導覽區域。

    • NavigationServer2D 會用此資源更新各區塊的導覽網格。

    • TileSet 編輯器在定義圖塊導覽區域時,會內部建立並使用此資源。

也參考

你可以透過 2D Navigation Polygon使用 AStarGrid2D 的格狀導覽 等範例專案,實際了解 2D 導覽的運作方式。

2D 場景設定

以下步驟說明如何建立最基本可用的 2D 導覽設定,會用到 NavigationServer2D 與 NavigationAgent2D 來進行路徑移動。

  1. 在場景中新增一個 NavigationRegion2D 節點。

  2. 點選該區塊節點,並新增一個 NavigationPolygon 資源至該節點。

    ../../_images/nav_2d_min_setup_step1.png
  3. 使用 NavigationPolygon 繪製工具定義可移動的導覽區域,然後在工具列按下 Bake NavigationPolygon 按鈕。

    ../../_images/nav_2d_min_setup_step2.png

    備註

    導覽網格定義角色(中心點)可以站立與移動的區域。請於導覽多邊形邊緣與碰撞物件間預留足夠距離,避免路徑跟隨角色被碰撞體卡住。

  4. 在場景新增 CharacterBody2D 節點,設置基本碰撞形狀與 Sprite 或 Mesh 作為顯示用。

  5. 在角色節點下新增一個 NavigationAgent2D 子節點。

    ../../_images/nav_2d_min_setup_step3.webp
  6. 將下列腳本加入 CharacterBody2D 節點。我們會確保於場景完全載入、NavigationServer 完成同步後再設定移動目標。

extends CharacterBody2D

var movement_speed: float = 200.0
var movement_target_position: Vector2 = Vector2(60.0,180.0)

@onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D

func _ready():
    # These values need to be adjusted for the actor's speed
    # and the navigation layout.
    navigation_agent.path_desired_distance = 4.0
    navigation_agent.target_desired_distance = 4.0

    # Make sure to not await during _ready.
    actor_setup.call_deferred()

func actor_setup():
    # Wait for the first physics frame so the NavigationServer can sync.
    await get_tree().physics_frame

    # Now that the navigation map is no longer empty, set the movement target.
    set_movement_target(movement_target_position)

func set_movement_target(movement_target: Vector2):
    navigation_agent.target_position = movement_target

func _physics_process(delta):
    if navigation_agent.is_navigation_finished():
        return

    var current_agent_position: Vector2 = global_position
    var next_path_position: Vector2 = navigation_agent.get_next_path_position()

    velocity = current_agent_position.direction_to(next_path_position) * movement_speed
    move_and_slide()

備註

在第一幀時,NavigationServer 的地圖尚未同步區域資料,此時任何路徑查詢都會回傳空結果。請於腳本中等待一幀,讓 NavigationServer 完成同步。