diff --git a/2d/navigation/README.md b/2d/navigation/README.md index 5020793917b..a06acdbc990 100644 --- a/2d/navigation/README.md +++ b/2d/navigation/README.md @@ -1,14 +1,13 @@ # Navigation Polygon 2D -Example of using 2D navigation using a -[`NavigationPolygon`](https://docs.godotengine.org/en/latest/classes/class_navigationpolygon.html) -in a [`NavigationPolygonInstance`](https://docs.godotengine.org/en/latest/classes/class_navigationpolygoninstance.html) node. -It uses the 2D navigation API to request a path between two points, -and then traverses the resulting path. +Example of using 2D navigation using: +- [`NavigationRegion2D`](https://docs.godotengine.org/en/latest/classes/class_navigationregion2d.html) +- [`NavigationPolygon`](https://docs.godotengine.org/en/latest/classes/class_navigationpolygon.html) +- [`NavigationAgent2D`](https://docs.godotengine.org/en/latest/classes/class_navigationagent2d.html) Language: GDScript -Renderer: GLES 2 +Renderer: Forward+ Check out this demo on the asset library: https://godotengine.org/asset-library/asset/117 diff --git a/2d/navigation/character.png.import b/2d/navigation/character.png.import index 73275cc31f6..c2f105fc58f 100644 --- a/2d/navigation/character.png.import +++ b/2d/navigation/character.png.import @@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/character.png-7a996d3b758d22c506b76a7c1539128 [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/navigation/character_navigation.gd b/2d/navigation/character_navigation.gd new file mode 100644 index 00000000000..c73166c1383 --- /dev/null +++ b/2d/navigation/character_navigation.gd @@ -0,0 +1,24 @@ +extends CharacterBody2D + +var movement_speed: float = 200.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 = 2.0 + navigation_agent.target_desired_distance = 2.0 + pass + +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() diff --git a/2d/navigation/level.tscn b/2d/navigation/level.tscn deleted file mode 100644 index 71d98eaac33..00000000000 --- a/2d/navigation/level.tscn +++ /dev/null @@ -1,32 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://cur17tkfqetf0"] - -[ext_resource type="Script" path="res://navigation.gd" id="1"] -[ext_resource type="Texture2D" uid="uid://bk26gi6qsuh18" path="res://map.png" id="2"] -[ext_resource type="Texture2D" uid="uid://b0wokaenwu7pj" path="res://character.png" id="3"] - -[sub_resource type="NavigationPolygon" id="NavigationPolygon_5ynhe"] -vertices = PackedVector2Array(682, 496, 696, 300, 704, 507, 495, 256, 589, 270, 540, 284, 466, 177, 490, 169, 531, 178, 477, 205, 446, 196, 621, 510, 667, 525, 606, 519, 529, 290, 288, 228, 228, 180, 276, 160, 315, 190, 600, 497, 576, 503, 202, 99, 314, 65, 311, 83, 436, 170, 452, 163, 201, 440, 246, 478, 223, 490, 211, 485, 146, 400, 185, 381, 586, 178, 596, 188, 474, 252, 462, 127, 479, 150, 416, 180, 395, 516, 302, 499, 320, 450, 354, 445, 535, 516, 538, 106, 537, 173, 493, 166, 506, 97, 514, 51, 486, 83, 327, 77, 309, 96, 306, 113, 272, 153, 219, 172, 178, 152, 148, 224, 189, 231, 171, 328, 176, 347, 259, 404, 432, 249, 365, 346, 525, 342, 314, 340, 271, 336, 241, 321, 235, 284, 242, 247, 324, 336, 616, 360, 645, 381, 645, 404, 614, 492) -polygons = [PackedInt32Array(0, 1, 2), PackedInt32Array(3, 4, 5), PackedInt32Array(6, 7, 8, 9, 10), PackedInt32Array(11, 0, 2, 12, 13), PackedInt32Array(3, 5, 14), PackedInt32Array(15, 16, 17, 18), PackedInt32Array(19, 11, 13, 20), PackedInt32Array(21, 22, 23), PackedInt32Array(6, 10, 24, 25), PackedInt32Array(26, 27, 28, 29, 30), PackedInt32Array(31, 26, 30), PackedInt32Array(32, 33, 3, 34), PackedInt32Array(18, 35, 36, 25, 24), PackedInt32Array(18, 24, 37), PackedInt32Array(38, 39, 40, 41, 42), PackedInt32Array(43, 44, 45, 46), PackedInt32Array(47, 43, 46, 48), PackedInt32Array(49, 47, 48, 50, 23), PackedInt32Array(21, 23, 50, 51, 52, 53, 54), PackedInt32Array(55, 54, 53, 56), PackedInt32Array(30, 55, 56, 57), PackedInt32Array(30, 57, 58), PackedInt32Array(31, 30, 58), PackedInt32Array(31, 58, 59, 40), PackedInt32Array(40, 59, 41), PackedInt32Array(18, 37, 60, 15), PackedInt32Array(20, 42, 41, 61, 60, 34, 3, 62), PackedInt32Array(63, 64, 65, 66, 67, 15, 60, 68), PackedInt32Array(61, 68, 60), PackedInt32Array(62, 69, 70, 71, 72, 19, 20), PackedInt32Array(62, 3, 14)] -outlines = [PackedVector2Array(314, 65, 311, 83, 327, 77, 514, 51, 538, 106, 537, 173, 493, 166, 506, 97, 486, 83, 309, 96, 306, 113, 272, 153, 219, 172, 189, 231, 171, 328, 176, 347, 259, 404, 354, 445, 365, 346, 324, 336, 314, 340, 271, 336, 241, 321, 235, 284, 242, 247, 288, 228, 228, 180, 276, 160, 315, 190, 462, 127, 479, 150, 452, 163, 466, 177, 490, 169, 531, 178, 477, 205, 446, 196, 436, 170, 416, 180, 432, 249, 474, 252, 586, 178, 596, 188, 495, 256, 589, 270, 540, 284, 529, 290, 525, 342, 616, 360, 645, 381, 645, 404, 614, 492, 600, 497, 621, 510, 682, 496, 696, 300, 704, 507, 667, 525, 606, 519, 576, 503, 535, 516, 395, 516, 302, 499, 320, 450, 185, 381, 201, 440, 246, 478, 223, 490, 211, 485, 146, 400, 148, 224, 178, 152, 202, 99)] - -[node name="Node2D" type="Node2D"] -script = ExtResource("1") - -[node name="Map" type="Sprite2D" parent="."] -position = Vector2(429.585, 287.32) -texture = ExtResource("2") - -[node name="Camera2D" type="Camera2D" parent="."] -offset = Vector2(420, 300) -current = true - -[node name="Character" type="Sprite2D" parent="."] -position = Vector2(228.464, 132.594) -scale = Vector2(0.5, 0.5) -texture = ExtResource("3") -offset = Vector2(0, -26) - -[node name="NavigationRegion2d" type="NavigationRegion2D" parent="."] -navpoly = SubResource("NavigationPolygon_5ynhe") - -[node name="NavigationAgent2d" type="NavigationAgent2D" parent="."] diff --git a/2d/navigation/map.png.import b/2d/navigation/map.png.import index b57f7a38ef2..c38ee705740 100644 --- a/2d/navigation/map.png.import +++ b/2d/navigation/map.png.import @@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/map.png-9eea34967fae34f4388f4a32a16da936.ctex [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/navigation/navigation.gd b/2d/navigation/navigation.gd index bf00912f2b3..8b8208c4f1c 100644 --- a/2d/navigation/navigation.gd +++ b/2d/navigation/navigation.gd @@ -1,60 +1,17 @@ extends Node2D -@export var character_speed: float = 400.0 -var path = [] - -@onready var character = $Character - -#var navmap = NavigationServer2D.map_create() - - -func _ready(): - pass - #NavigationServer2D.region_set_map(navmap, $NavigationRegion2d.get_rid()) - - -func _process(delta): - character.position = $NavigationAgent2d.get_next_location() - var walk_distance = character_speed * delta - #move_along_path(walk_distance) - - # The "click" event is a custom input action defined in # Project > Project Settings > Input Map tab. func _unhandled_input(event): if not event.is_action_pressed("click"): return - _update_navigation_path(Vector2(), get_local_mouse_position()) - -#func move_along_path(distance): -# return -# var last_point = character.position -# while path.size(): -# var distance_between_points = last_point.distance_to(path[0]) -# # The position to move to falls between two points. -# if distance <= distance_between_points: -# character.position = last_point.lerp(path[0], distance / distance_between_points) -# return -# # The position is past the end of the segment. -# distance -= distance_between_points -# last_point = path[0] -# path.remove(0) -# # The character reached the end of the path. -# character.position = last_point -# set_process(false) + navigate_to(get_local_mouse_position()) var drawpos = Vector2() -func _update_navigation_path(start_position, end_position): - # get_simple_path is part of the Node2D class. - # It returns a PackedVector2Array of points that lead you - # from the start_position to the end_position. - $NavigationAgent2d.set_target_location(end_position) - drawpos = end_position +func navigate_to(pos): + $Character/NavigationAgent2D.target_position = pos + drawpos = pos queue_redraw() - # The first point is always the start_position. - # We don't need it in this example as it corresponds to the character's position. - #path.remove(0) - #set_process(true) func _draw(): - draw_circle(drawpos, 10, Color.RED) + draw_circle(drawpos, 5, Color.RED) diff --git a/2d/navigation/navigation.tres b/2d/navigation/navigation.tres new file mode 100644 index 00000000000..ac30ba1696b --- /dev/null +++ b/2d/navigation/navigation.tres @@ -0,0 +1,6 @@ +[gd_resource type="NavigationPolygon" format=3 uid="uid://dx268exgke7v5"] + +[resource] +vertices = PackedVector2Array(336, 360, 316, 336, 394, 348, 388, 375, 356, 366, 465, 272, 559, 285, 509, 299, 500, 297, 482, 295, 495, 301, 293, 349, 263, 302, 479, 110, 481, 69, 508, 121, 505, 125, 408, 283, 442, 269, 643, 309, 619, 331, 621, 268, 653, 297, 587, 527, 654, 512, 672, 521, 638, 538, 579, 535, 589, 405, 584, 375, 615, 396, 615, 418, 665, 316, 257, 243, 312, 225, 333, 241, 268, 272, 215, 264, 494, 375, 495, 358, 171, 114, 283, 80, 280, 97, 277, 109, 454, 96, 297, 93, 172, 458, 215, 492, 193, 504, 181, 500, 118, 415, 154, 393, 465, 181, 505, 185, 436, 193, 447, 218, 417, 211, 408, 183, 421, 177, 574, 473, 584, 505, 431, 143, 448, 165, 284, 207, 385, 192, 451, 453, 499, 305, 485, 476, 447, 482, 506, 512, 568, 510, 545, 517, 274, 127, 239, 169, 188, 184, 558, 192, 546, 169, 543, 153, 551, 153, 576, 162, 586, 169, 565, 202, 325, 459, 346, 431, 341, 450, 337, 479, 315, 478, 232, 423, 304, 472, 318, 333, 361, 516, 503, 530, 361, 530, 273, 515, 295, 502, 292, 466, 147, 366, 284, 356, 244, 350, 212, 336, 206, 300, 621, 171, 671, 191, 672, 213, 668, 286, 603, 230, 614, 175, 613, 155, 572, 127, 543, 99, 552, 68, 578, 70, 614, 83, 630, 93, 641, 104, 653, 125, 400, 263, 390, 283, 371, 198, 118, 236, 162, 240, 140, 341) +polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3, 4), PackedInt32Array(5, 6, 7, 8), PackedInt32Array(9, 5, 8, 10), PackedInt32Array(1, 0, 11, 12), PackedInt32Array(13, 14, 15, 16), PackedInt32Array(5, 9, 17, 18), PackedInt32Array(19, 20, 21, 22), PackedInt32Array(23, 24, 25, 26, 27), PackedInt32Array(28, 29, 30, 31), PackedInt32Array(32, 25, 24, 19, 22), PackedInt32Array(33, 34, 35, 36, 37), PackedInt32Array(29, 28, 38, 39), PackedInt32Array(40, 41, 42, 43), PackedInt32Array(14, 13, 44), PackedInt32Array(45, 14, 44, 43, 42), PackedInt32Array(46, 47, 48, 49), PackedInt32Array(46, 49, 50, 51), PackedInt32Array(52, 13, 16, 53), PackedInt32Array(54, 52, 53, 55, 56), PackedInt32Array(54, 56, 57, 58), PackedInt32Array(59, 28, 31, 60), PackedInt32Array(61, 62, 58, 63), PackedInt32Array(63, 58, 57, 64), PackedInt32Array(65, 9, 10, 66, 39), PackedInt32Array(65, 39, 38, 67, 68), PackedInt32Array(69, 59, 60, 70, 71), PackedInt32Array(40, 43, 72, 73, 74), PackedInt32Array(75, 76, 77, 78, 79, 80, 81), PackedInt32Array(82, 0, 4, 83, 84), PackedInt32Array(65, 68, 84, 83), PackedInt32Array(82, 84, 85, 86), PackedInt32Array(87, 82, 86, 88), PackedInt32Array(12, 89, 1), PackedInt32Array(70, 23, 27, 71), PackedInt32Array(90, 69, 71, 91, 92), PackedInt32Array(90, 92, 93, 94), PackedInt32Array(94, 93, 95, 88), PackedInt32Array(87, 88, 95, 51, 96), PackedInt32Array(12, 11, 97, 98, 99, 100, 37), PackedInt32Array(36, 12, 37), PackedInt32Array(101, 102, 103, 104, 22, 21, 105, 106), PackedInt32Array(107, 108, 109, 110, 111, 112, 113, 114, 115, 102), PackedInt32Array(101, 107, 102), PackedInt32Array(106, 105, 81, 80), PackedInt32Array(75, 81, 5, 18), PackedInt32Array(116, 18, 17, 117), PackedInt32Array(116, 117, 118, 64), PackedInt32Array(63, 64, 118), PackedInt32Array(63, 118, 34, 33), PackedInt32Array(63, 33, 74, 73), PackedInt32Array(119, 40, 74, 120), PackedInt32Array(119, 120, 121, 50), PackedInt32Array(50, 121, 96, 51)]) +outlines = Array[PackedVector2Array]([PackedVector2Array(215, 492, 193, 504, 181, 500, 118, 415, 118, 236, 171, 114, 283, 80, 280, 97, 297, 93, 481, 69, 508, 121, 505, 125, 505, 185, 447, 218, 417, 211, 408, 183, 385, 192, 400, 263, 442, 269, 558, 192, 546, 169, 543, 153, 551, 153, 576, 162, 586, 169, 614, 175, 621, 171, 613, 155, 572, 127, 543, 99, 552, 68, 578, 70, 614, 83, 630, 93, 641, 104, 653, 125, 671, 191, 672, 213, 668, 286, 653, 297, 665, 316, 672, 521, 638, 538, 579, 535, 545, 517, 503, 530, 361, 530, 273, 515, 292, 466, 154, 393, 172, 458), PackedVector2Array(188, 184, 257, 243, 215, 264, 206, 300, 212, 336, 244, 350, 284, 356, 293, 349, 336, 360, 325, 459, 232, 423, 147, 366, 140, 341, 162, 240), PackedVector2Array(239, 169, 274, 127, 277, 109, 454, 96, 479, 110, 465, 181, 436, 193, 421, 177, 448, 165, 431, 143, 284, 207), PackedVector2Array(312, 225, 371, 198, 390, 283, 408, 283, 482, 295, 451, 453, 346, 431, 356, 366, 388, 375, 394, 348, 316, 336, 318, 333, 263, 302, 268, 272, 333, 241), PackedVector2Array(341, 450, 337, 479, 315, 478, 304, 472, 295, 502, 361, 516, 506, 512, 574, 473, 589, 405, 494, 375, 485, 476, 447, 482), PackedVector2Array(565, 202, 603, 230, 621, 268, 619, 331, 643, 309, 654, 512, 587, 527, 568, 510, 584, 505, 615, 418, 615, 396, 584, 375, 495, 358, 499, 305, 495, 301, 500, 297, 509, 299, 559, 285, 465, 272)]) diff --git a/2d/navigation/navigation.tscn b/2d/navigation/navigation.tscn new file mode 100644 index 00000000000..0514f992996 --- /dev/null +++ b/2d/navigation/navigation.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=7 format=3 uid="uid://bjgad00c2xiuc"] + +[ext_resource type="Script" path="res://navigation.gd" id="1_j3vjp"] +[ext_resource type="Texture2D" uid="uid://bk26gi6qsuh18" path="res://map.png" id="2_nxfkp"] +[ext_resource type="NavigationPolygon" uid="uid://dx268exgke7v5" path="res://navigation.tres" id="3_5ufs1"] +[ext_resource type="Script" path="res://character_navigation.gd" id="3_abq88"] +[ext_resource type="Texture2D" uid="uid://b0wokaenwu7pj" path="res://character.png" id="4_55b5j"] + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_7hahy"] +radius = 7.0 +height = 22.0 + +[node name="Navigation" type="Node2D"] +script = ExtResource("1_j3vjp") + +[node name="Map" type="Sprite2D" parent="."] +z_index = -1 +position = Vector2(400, 302) +texture = ExtResource("2_nxfkp") + +[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."] +navigation_polygon = ExtResource("3_5ufs1") + +[node name="Character" type="CharacterBody2D" parent="."] +position = Vector2(210, 138) +script = ExtResource("3_abq88") + +[node name="Sprite2D" type="Sprite2D" parent="Character"] +position = Vector2(0, -3) +scale = Vector2(0.3, 0.3) +texture = ExtResource("4_55b5j") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Character"] +position = Vector2(0, -3) +shape = SubResource("CapsuleShape2D_7hahy") + +[node name="NavigationAgent2D" type="NavigationAgent2D" parent="Character"] diff --git a/2d/navigation/project.godot b/2d/navigation/project.godot index ab5f571d1b0..dc9ca6c712d 100644 --- a/2d/navigation/project.godot +++ b/2d/navigation/project.godot @@ -14,10 +14,10 @@ config/name="Navigation Polygon 2D" config/description="Example of using 2D navigation using a NavigationPolygon in a NavigationPolygonInstance node. It uses the 2D navigation API to request a path between two points, and then traverses the resulting path." -run/main_scene="res://level.tscn" -config/features=PackedStringArray("4.0") -config/icon="res://icon.webp" config/tags=PackedStringArray("2d", "ai", "demo", "official") +run/main_scene="res://navigation.tscn" +config/features=PackedStringArray("4.1") +config/icon="res://icon.webp" [display] @@ -29,7 +29,7 @@ window/stretch/aspect="expand" click={ "deadzone": 0.5, -"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"pressed":false,"double_click":false,"script":null) +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) ] }