Сегодня я разберу структуру и код программы на Godot — Navigation Mesh Chunks 2D.годот программирование Mesh Chunks 2
Проект Navigation Mesh Chunks 2D представляет собой одну сцену с корневым узлом Node2D, внутри которого размещены Camera2D, три узла Node2D и CanvasLayer. В первом Node2D находится StaticBody2D с тремя дочерними CollisionPolygon2D. Второй Node2D содержит три объекта NavigationAgent2D. Третий Node2D не имеет дочерних элементов. CanvasLayer, в свою очередь, включает текстовые надписи (Label) и ColorRect, отображающие названия линий NavigationAgent2D:
Осталось разобрать код файла navmesh_chunks_demo_2d.gd. Рассмотрим функцию create_region_chunks. Она вызывается только один раз за время работы программы и выполняет следующие действия: создает прямоугольные области (чанки), вычисляет их пересечения друг с другом, а затем округляет пересечения этих чанков с полигонами CollisionPolygon2D:
var input_geometry_bounds: Rect2 = p_source_geometry.get_bounds()
var start_chunk: Vector2 = floor(
input_geometry_bounds.position / p_chunk_size
)
var end_chunk: Vector2 = floor(
(input_geometry_bounds.position + input_geometry_bounds.size)
/ p_chunk_size
)
Для определения границ чанков экранное пространство делится на сегменты размером p_chunk_size (256 пикселей). В результате мы получаем набор областей-чанков, внутри которых могут располагаться объекты NavigationAgent2D:
for chunk_y in range(start_chunk.y, end_chunk.y + 1):
for chunk_x in range(start_chunk.x, end_chunk.x + 1):
var chunk_id: Vector2i = Vector2i(chunk_x, chunk_y)
var chunk_bounding_box: Rect2 = Rect2(Vector2(chunk_x, chunk_y) * p_chunk_size,Vector2(p_chunk_size, p_chunk_size),)
Определяем прямоугольники(чанки)
var baking_bounds: Rect2 = chunk_bounding_box.grow(p_chunk_size)
Затем прямоугольники расширяются по периметру таким образом, чтобы они перекрывались с соседними чанками, обеспечивая плавные переходы между областями:
var chunk_navmesh: NavigationPolygon = NavigationPolygon.new()
chunk_navmesh.parsed_geometry_type = NavigationPolygon.PARSED_GEOMETRY_STATIC_COLLIDERS
chunk_navmesh.baking_rect = baking_bounds
chunk_navmesh.border_size = p_chunk_size
chunk_navmesh.agent_radius = p_agent_radius
NavigationServer2D.bake_from_source_geometry_data(chunk_navmesh, p_source_geometry)
После завершения всех расчетов мы запекаем (финализируем) геометрию полученных прямоугольников, чтобы зафиксировать их в навигационной сетке:
var navmesh_vertices: PackedVector2Array = chunk_navmesh.vertices
for i in navmesh_vertices.size():
var vertex: Vector2 = navmesh_vertices[i]
navmesh_vertices[i] = vertex.snappedf(map_cell_size * 0.1)
chunk_navmesh.vertices = navmesh_vertices
Для каждого чанка берется его расширенная область (baking_bounds), из которой вычитаются все CollisionPolygon2D, попадающие в этот диапазон. На основе полученных данных строятся многоугольники проходимой области. Углы этих многоугольников являются вершинами (vertices). Далее координаты всех вершин округляются с шагом 0.1, чтобы обеспечить их совпадение на стыках соседних чанков:
var chunk_region: NavigationRegion2D = NavigationRegion2D.new()
chunk_region.navigation_polygon = chunk_navmesh
chunks_root_node.add_child(chunk_region)
chunk_id_to_region[chunk_id] = chunk_region
Созданные прямоугольники (чанки) добавляются в качестве дочерних объектов к узлу NavigationRegion2D, который, в свою очередь, размещается внутри Node2D с именем ChunksContainer:
годот программирование Mesh Chunks 2.Конец
Мы разобрали код и структуру примера Godot Navigation Mesh Chunks 2D. В следующий раз мы восстановим этот проект — пройдем путь от пустой сцены до готового решения. Спасибо за внимание!
