fix: ground physics on real Terrain3D surface

Enable Terrain3D collision_mode=1 so the sculpted landscape provides real physical ground for player and NPCs. Disable GreyboxGround collision (layer/mask = 0) -- it is no longer the active physical floor.

NpcVisual no longer flattens nav waypoint Y to its current elevation. It now follows 3D path points and uses gravity (30 m/s^2) like the player, settling to terrain surface via is_on_floor() + Terrain3D collision. The flat NavigationMesh_greybox still provides correct lateral guidance; physics handles vertical grounding on slopes.

This fixes the player-walking-through-slopes bug and makes NPC movement follow actual terrain elevation for the village area (gentle slopes, ~2.4m noise amplitude). All 10 scenarios pass.
This commit is contained in:
2026-07-07 16:56:15 +02:00
parent 1c389ec23d
commit 41b515f474
2 changed files with 8 additions and 4 deletions
+5 -3
View File
@@ -185,8 +185,7 @@ func _physics_process(delta: float) -> void:
return return
var next_pos := current_path[path_index] var next_pos := current_path[path_index]
var flat_next_pos := Vector3(next_pos.x, global_position.y, next_pos.z) var to_next := next_pos - global_position
var to_next := flat_next_pos - global_position
if to_next.length() <= waypoint_reached_distance: if to_next.length() <= waypoint_reached_distance:
path_index += 1 path_index += 1
@@ -197,7 +196,10 @@ func _physics_process(delta: float) -> void:
velocity.x = direction.x * move_speed velocity.x = direction.x * move_speed
velocity.z = direction.z * move_speed velocity.z = direction.z * move_speed
velocity.y = 0.0 if not is_on_floor():
velocity.y -= 30.0 * delta
else:
velocity.y = 0.0
move_and_slide() move_and_slide()
if not global_position.is_equal_approx(prev_pos): if not global_position.is_equal_approx(prev_pos):
+3 -1
View File
@@ -121,6 +121,8 @@ script = ExtResource("3_world")
navigation_mesh = SubResource("NavigationMesh_greybox") navigation_mesh = SubResource("NavigationMesh_greybox")
[node name="GreyboxGround" type="StaticBody3D" parent="NavigationRegion3D"] [node name="GreyboxGround" type="StaticBody3D" parent="NavigationRegion3D"]
collision_layer = 0
collision_mask = 0
[node name="Mesh" type="MeshInstance3D" parent="NavigationRegion3D/GreyboxGround"] [node name="Mesh" type="MeshInstance3D" parent="NavigationRegion3D/GreyboxGround"]
visible = false visible = false
@@ -136,7 +138,7 @@ data_directory = "res://terrain/jajce/data"
material = SubResource("Terrain3DMaterial_jajce") material = SubResource("Terrain3DMaterial_jajce")
assets = ExtResource("1_assets") assets = ExtResource("1_assets")
collision_mask = 3 collision_mask = 3
collision_mode = 0 collision_mode = 1
top_level = true top_level = true
[node name="FortressBlockout" type="Node3D" parent="."] [node name="FortressBlockout" type="Node3D" parent="."]