diff options
-rw-r--r-- | prefabs/bsp_level_generator.tscn | 7 | ||||
-rw-r--r-- | prefabs/enemy.tscn | 2 | ||||
-rw-r--r-- | prefabs/test_arena.tscn | 1 | ||||
-rw-r--r-- | scripts/bsp_level_generator.gd | 11 | ||||
-rw-r--r-- | scripts/enemy.gd | 48 |
5 files changed, 62 insertions, 7 deletions
diff --git a/prefabs/bsp_level_generator.tscn b/prefabs/bsp_level_generator.tscn index dbb62a5..ea0cfd7 100644 --- a/prefabs/bsp_level_generator.tscn +++ b/prefabs/bsp_level_generator.tscn @@ -1,6 +1,11 @@ -[gd_scene load_steps=2 format=3 uid="uid://w7hxcvuvud"] +[gd_scene load_steps=3 format=3 uid="uid://w7hxcvuvud"] [ext_resource type="Script" path="res://scripts/bsp_level_generator.gd" id="1_6jn1x"] +[sub_resource type="NavigationMesh" id="NavigationMesh_q1fo6"] + [node name="BspLevelGenerator" type="Node3D"] script = ExtResource("1_6jn1x") + +[node name="NavigationRegion3D" type="NavigationRegion3D" parent="."] +navigation_mesh = SubResource("NavigationMesh_q1fo6") diff --git a/prefabs/enemy.tscn b/prefabs/enemy.tscn index 9ed692e..71e35f8 100644 --- a/prefabs/enemy.tscn +++ b/prefabs/enemy.tscn @@ -26,4 +26,6 @@ shape = SubResource("CapsuleShape3D_s5qw4") [node name="HitTimer" type="Timer" parent="."] wait_time = 0.2 +[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."] + [connection signal="timeout" from="HitTimer" to="." method="_on_hit_timer_timeout"] diff --git a/prefabs/test_arena.tscn b/prefabs/test_arena.tscn index 81bd235..7bdeba8 100644 --- a/prefabs/test_arena.tscn +++ b/prefabs/test_arena.tscn @@ -113,6 +113,5 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20, 0, 20) collision_layer = 5 motion_mode = 0 target = NodePath("../Player") -gravity_enabled = true [node name="BspLevelGenerator" parent="." instance=ExtResource("4_501hd")] diff --git a/scripts/bsp_level_generator.gd b/scripts/bsp_level_generator.gd index 5d70569..87806e2 100644 --- a/scripts/bsp_level_generator.gd +++ b/scripts/bsp_level_generator.gd @@ -123,7 +123,16 @@ func generate_geo(grid: Array[Tile]): csg_root.add_child(box) csg_root.use_collision = true - add_child(csg_root) + $NavigationRegion3D.add_child(csg_root) + + # We need to delay baking the nav mesh as + # the CSG won't be generated immediately + call_deferred("bake_nav") + +func bake_nav(): + print("Baking mesh") + $NavigationRegion3D.bake_navigation_mesh(false) + print("done baking") func _ready() -> void: var starting_axis = randi_range(0, 1) diff --git a/scripts/enemy.gd b/scripts/enemy.gd index 569905f..6be60c7 100644 --- a/scripts/enemy.gd +++ b/scripts/enemy.gd @@ -6,7 +6,12 @@ extends CharacterBody3D @export var target: Node3D ## Whether to use gravity on enemy -@export var gravity_enabled: bool = false +@export var gravity_enabled: bool = true + +## Use nav mesh or dumb path finding +@export var use_nav_mesh: bool = true + +@onready var nav_agent: NavigationAgent3D = $NavigationAgent3D var has_astar: bool = false var astar: AStar3D @@ -15,9 +20,17 @@ var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity") var original_color: Color +var mesh_ready = false + func _ready() -> void: if gravity_enabled: motion_mode = MotionMode.MOTION_MODE_GROUNDED + + NavigationServer3D.connect("map_changed", map_changed) + +func map_changed(_rid): + print("Map changed") + mesh_ready = true func chase_target(delta: float) -> void: var target_pos = target.position @@ -34,19 +47,46 @@ func chase_target(delta: float) -> void: velocity.y -= gravity * delta move_and_slide() + +func update_target_location(target_location: Vector3): + nav_agent.target_position = target_location + +func chase_nav_mesh(delta: float): + if not mesh_ready: + return + + if target != null: + update_target_location(target.global_position) + + var current_location = global_transform.origin + var next_location = nav_agent.get_next_path_position() + var new_velocity = (next_location - current_location).normalized() * speed + + # We only want to navigate on XZ plane + new_velocity.y = 0 + + velocity = new_velocity + + if not is_on_floor() and gravity_enabled: + velocity.y -= gravity * delta + move_and_slide() func _physics_process(delta: float) -> void: if target == null: return + if Input.is_action_pressed("ui_right"): + return + + if use_nav_mesh: + chase_nav_mesh(delta) + return + if not has_astar: # Just try to chase player directly chase_target(delta) return - if Input.is_action_pressed("ui_right"): - return - var target_pos = target.position var closest_me = astar.get_closest_point(position) var closest_target = astar.get_closest_point(target_pos) |