godot-tscn-format
Godot 4.x .tscn 场景文件纯文本格式规范与 AI 操作指南 — 文件结构、资源引用、 Transform 变换、属性值格式、信号连接,以及 AI 直接读写 .tscn 文件的操作方法。
NavigationAgent2D使用、AStarGrid2D算法、自定义A*实现、流式寻路及性能优化。用于2D/3D导航系统、动态障碍物避让、游戏AI导航等场景。
$ npx -y skills add 925236118/AlphaAgent --skill godot-navigation-system --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/godot-navigation-systemContext preview
The summary Claude sees to decide when to auto-load this skill.
NavigationAgent2D使用、AStarGrid2D算法、自定义A*实现、流式寻路及性能优化。用于2D/3D导航系统、动态障碍物避让、游戏AI导航等场景。
name: godot-navigation-system description: NavigationAgent2D使用、AStarGrid2D算法、自定义A*实现、流式寻路及性能优化。用于2D/3D导航系统、动态障碍物避让、游戏AI导航等场景。
Godot 4 导航系统完整指南,涵盖 NavigationAgent2D、AStarGrid2D、自定义 A* 算法、流场寻路及性能优化策略。
NavigationAgent2D 是 Godot 4 推荐的 2D 导航解决方案,封装了 NavigationServer 的复杂操作。
# navigation_agent_2d.gd
class_name NavigationAgent2D
extends NavigationAgent2D
signal navigation_finished
signal path_changed
signal target_reached
@export var actor: CharacterBody2D
@export var move_speed: float = 200.0
var _target_position: Vector2 = Vector2.ZERO
func _ready() -> void:
# 设置代理半径(障碍物避让)
agent_height = 0
agent_max_speed = move_speed
# 连接信号
navigation_finished.connect(_on_navigation_finished)
path_changed.connect(_on_path_changed)
target_reached.connect(_on_target_reached)
# 等待NavigationServer同步
await get_tree().physics_frame
await get_tree().physics_frame
func _physics_process(delta: float) -> void:
if actor and _target_position != Vector2.ZERO:
if is_navigation_finished():
return
var next_pos := get_next_path_position()
var current_pos := actor.global_position
var new_velocity := (next_pos - current_pos).normalized() * move_speed
actor.velocity = new_velocity
actor.move_and_slide()
func set_target(world_position: Vector2) -> void:
_target_position = world_position
target_position = world_position
func _on_navigation_finished() -> void:
navigation_finished.emit()
func _on_path_changed() -> void:
path_changed.emit()
func _on_target_reached() -> void:
target_reached.emit()# navigation_region.gd
class_name NavigationRegion
extends NavigationRegion2D
@export var tile_map: TileMap
@export var bake_on_ready: bool = true
func _ready() -> void:
if bake_on_ready:
await get_tree().physics_frame
bake_navigation_polygon()
# 从 TileMap 几何数据生成导航多边形
func bake_from_tilemap() -> void:
var polygon := NavigationPolygon.new()
var outline: Array[Vector2] = []
var used_rect := tile_map.get_used_rect()
for x in range(used_rect.size.x):
for y in range(used_rect.size.y):
var cell := Vector2i(used_rect.position.x + x, used_rect.position.y + y)
var tile_data := tile_map.get_cell_tile_data(0, cell)
if tile_data and tile_data.get_custom_data("obstacle"):
# 障碍物格子不加入导航
continue
var world_pos := tile_map.map_to_local(cell)
outline.append(world_pos)
if not outline.is_empty():
polygon.add_outline(outline)
polygon.make_polygons_from_outlines()
navigation_polygon = polygon
bake_navigation_polygon()# dynamic_obstacle.gd
class_name DynamicObstacle
extends Area2D
@export var radius: float = 32.0
@export var navigation_region: NavigationRegion
var _last_position: Vector2
func _ready() -> void:
area_entered.connect(_on_area_entered)
area_exited.connect(_on_area_exited)
func _physics_process(_delta: float) -> void:
if global_position != _last_position:
_last_position = global_position
_update_navigation()
func _update_navigation() -> void:
# 简单实现:移动时重新烘焙导航网格
# 生产环境建议使用 NavigationMesh::update()
if navigation_region:
navigation_region.bake_navigation_polygon()
func _on_area_entered(area: Area2D) -> void:
# 障碍物进入逻辑
pass
func _on_area_exited(area: Area2D) -> void:
# 障碍物离开逻辑
passAStarGrid2D 是 Godot 4 内置的高效网格寻路组件,适合规则网格的快速 A* 搜索。
# astar_grid_2d.gd
class_name AStarGrid2D
extends Node
@export var tile_map: TileMap
@export var obstacles_layer: int = 0
var _grid: AStarGrid2D
func _ready() -> void:
_setup_grid()
func _setup_grid() -> void:
var region := tile_map.get_used_rect()
_grid = AStarGrid2D.new()
_grid.size = region.size
_grid.offset = tile_map.tile_set.tile_size / 2
_grid.cell_size = tile_map.tile_set.tile_size
_grid.center = false
_grid.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_NEVER
_grid.update()
# 标记障碍物
for cell in tile_map.get_used_cells(obstacles_layer):
var tile_data := tile_map.get_cell_tile_data(obstacles_layer, cell)
if tile_data and tile_data.get_custom_data("obstacle"):
_grid.set_point_solid(cell - region.position)
func find_path(start: Vector2i, end: Vector2i) -> PackedVector2Array:
var region := tile_map.get_used_rect()
var local_start := start - region.position
var local_end := end - region.position
if not _grid.is_point_inside(local_start) or not _grid.is_point_inside(local_end):
return PackedVector2Array()
if _grid.is_point_solid(local_start) or _grid.is_point_solid(local_end):
return PackedVector2Array()
var path := _grid.get_point_path(local_start, local_end)
# 转换回世界坐标
var world_path := PackedVector2Array()
for point in path:
world_path.append(tile_map.map_to_local(point + region.position))
return world_path
func is_walkable(cell: Vector2i) -> bool:
var region := tile_map.get_used_rect()
var local_cell := cell - region.position
if not _grid.is_point_inside(local_cell):
return false
return not _grid.is_point_solid(local_cell)
func set_obstacle(cell: Vector2i, obstacle: bool) -> void:
var region := tile_map.get_used_rect()
var local_cell := cell - region.position
if obstacle:
_grid.set_point_solid(local_cell)
else:
_grid.clear_point(local_cell)# weighted_astar_grid.gd
class_name WeightedAStarGrid
extends AStarGrid2D
var _cell_weights: Dictionary = {}
func _ready() -> void:
_setup_grid()
func _setup_grid()Godot 4.x .tscn 场景文件纯文本格式规范与 AI 操作指南 — 文件结构、资源引用、 Transform 变换、属性值格式、信号连接,以及 AI 直接读写 .tscn 文件的操作方法。
Godot 4 Buff系统完整实现,支持状态效果管理、持续时间、循环效果、层叠机制等。使用Resource+Component架构。