NS-23: terminal collision, nav around obstacle, agent under region
- Add BoxShape3D to PrototypeTerminal (layer 1, walkable) so the player cannot pass through; matches terminal mesh size. - Bake navigation from collision layer 1 only so the player (layer 2) is not merged into the mesh; reparent Player under NavigationRegion3D so NavigationAgent3D resolves a valid map. - Restore nav waypoint following for long horizontal legs; keep horizontal steering toward next/goal so bump departure behavior stays sane.pull/23/head
parent
05d7916cc7
commit
a5ec8df4a7
|
|
@ -33,6 +33,9 @@ size = Vector3(0.9, 1, 0.4)
|
||||||
[sub_resource type="StandardMaterial3D" id="Mat_terminal"]
|
[sub_resource type="StandardMaterial3D" id="Mat_terminal"]
|
||||||
albedo_color = Color(0.28, 0.38, 0.45, 1)
|
albedo_color = Color(0.28, 0.38, 0.45, 1)
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape3D" id="BoxShape3D_terminal"]
|
||||||
|
size = Vector3(0.9, 1, 0.4)
|
||||||
|
|
||||||
[sub_resource type="BoxMesh" id="BoxMesh_marker"]
|
[sub_resource type="BoxMesh" id="BoxMesh_marker"]
|
||||||
size = Vector3(0.22, 0.35, 0.22)
|
size = Vector3(0.22, 0.35, 0.22)
|
||||||
|
|
||||||
|
|
@ -74,7 +77,7 @@ albedo_color = Color(0.32, 0.38, 0.55, 1)
|
||||||
|
|
||||||
[sub_resource type="NavigationMesh" id="NavigationMesh_district"]
|
[sub_resource type="NavigationMesh" id="NavigationMesh_district"]
|
||||||
geometry_parsed_geometry_type = 2
|
geometry_parsed_geometry_type = 2
|
||||||
geometry_collision_mask = 4294967295
|
geometry_collision_mask = 1
|
||||||
geometry_source_geometry_mode = 0
|
geometry_source_geometry_mode = 0
|
||||||
cell_size = 0.15
|
cell_size = 0.15
|
||||||
cell_height = 0.15
|
cell_height = 0.15
|
||||||
|
|
@ -111,13 +114,17 @@ mesh = SubResource("BoxMesh_floor")
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.1, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.1, 0)
|
||||||
shape = SubResource("BoxShape3D_floor")
|
shape = SubResource("BoxShape3D_floor")
|
||||||
|
|
||||||
[node name="PrototypeTerminal" type="StaticBody3D" parent="World/NavigationRegion3D" unique_id=1700001]
|
[node name="PrototypeTerminal" type="StaticBody3D" parent="World/NavigationRegion3D" unique_id=1700001 groups=["walkable"]]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||||
|
collision_layer = 1
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="World/NavigationRegion3D/PrototypeTerminal" unique_id=1700002]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="World/NavigationRegion3D/PrototypeTerminal" unique_id=1700002]
|
||||||
mesh = SubResource("BoxMesh_terminal")
|
mesh = SubResource("BoxMesh_terminal")
|
||||||
surface_material_override/0 = SubResource("Mat_terminal")
|
surface_material_override/0 = SubResource("Mat_terminal")
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="World/NavigationRegion3D/PrototypeTerminal" unique_id=1700006]
|
||||||
|
shape = SubResource("BoxShape3D_terminal")
|
||||||
|
|
||||||
[node name="InteractionMarkers" type="Node3D" parent="World" unique_id=1700003]
|
[node name="InteractionMarkers" type="Node3D" parent="World" unique_id=1700003]
|
||||||
script = ExtResource("6_rad")
|
script = ExtResource("6_rad")
|
||||||
|
|
||||||
|
|
@ -189,7 +196,7 @@ mesh = SubResource("BoxMesh_obstacle")
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||||
shape = SubResource("BoxShape3D_obstacle")
|
shape = SubResource("BoxShape3D_obstacle")
|
||||||
|
|
||||||
[node name="Player" type="CharacterBody3D" parent="." unique_id=352931696]
|
[node name="Player" type="CharacterBody3D" parent="World/NavigationRegion3D" unique_id=352931696]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 0.9, -5)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 0.9, -5)
|
||||||
collision_layer = 2
|
collision_layer = 2
|
||||||
collision_mask = 1
|
collision_mask = 1
|
||||||
|
|
@ -198,10 +205,10 @@ floor_snap_length = 0.28
|
||||||
safe_margin = 0.045
|
safe_margin = 0.045
|
||||||
script = ExtResource("2_player")
|
script = ExtResource("2_player")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Player" unique_id=1695755590]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="World/NavigationRegion3D/Player" unique_id=1695755590]
|
||||||
shape = SubResource("CapsuleShape3D_player")
|
shape = SubResource("CapsuleShape3D_player")
|
||||||
|
|
||||||
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="Player" unique_id=8880002]
|
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="World/NavigationRegion3D/Player" unique_id=8880002]
|
||||||
avoidance_enabled = false
|
avoidance_enabled = false
|
||||||
path_desired_distance = 0.35
|
path_desired_distance = 0.35
|
||||||
target_desired_distance = 0.35
|
target_desired_distance = 0.35
|
||||||
|
|
@ -209,7 +216,7 @@ path_height_offset = 0.0
|
||||||
radius = 0.4
|
radius = 0.4
|
||||||
height = 1.0
|
height = 1.0
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Player" unique_id=2027034386]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="World/NavigationRegion3D/Player" unique_id=2027034386]
|
||||||
mesh = SubResource("CapsuleMesh_player")
|
mesh = SubResource("CapsuleMesh_player")
|
||||||
|
|
||||||
[node name="GroundPick" type="Node3D" parent="." unique_id=2500001]
|
[node name="GroundPick" type="Node3D" parent="." unique_id=2500001]
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ var _move_reject_msg_token: int = 0
|
||||||
|
|
||||||
@onready var _camera: Camera3D = $World/Camera3D
|
@onready var _camera: Camera3D = $World/Camera3D
|
||||||
@onready var _nav_region: NavigationRegion3D = $World/NavigationRegion3D
|
@onready var _nav_region: NavigationRegion3D = $World/NavigationRegion3D
|
||||||
@onready var _player: CharacterBody3D = $Player
|
@onready var _player: CharacterBody3D = $World/NavigationRegion3D/Player
|
||||||
@onready var _ground_pick: Node3D = $GroundPick
|
@onready var _ground_pick: Node3D = $GroundPick
|
||||||
@onready var _authority: Node = $PositionAuthorityClient
|
@onready var _authority: Node = $PositionAuthorityClient
|
||||||
@onready var _radius_preview: Node3D = $World/InteractionMarkers
|
@onready var _radius_preview: Node3D = $World/InteractionMarkers
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ const ARRIVE_EPS: float = 0.35
|
||||||
const VERT_ARRIVE_EPS: float = 0.055
|
const VERT_ARRIVE_EPS: float = 0.055
|
||||||
const MAX_CLIMB_SPEED: float = 2.6
|
const MAX_CLIMB_SPEED: float = 2.6
|
||||||
const MAX_DESCENT_SPEED: float = 2.2
|
const MAX_DESCENT_SPEED: float = 2.2
|
||||||
|
const DIRECT_APPROACH_RADIUS: float = 0.85
|
||||||
|
|
||||||
var _has_walk_goal: bool = false
|
var _has_walk_goal: bool = false
|
||||||
var _auth_walk_goal: Vector3 = Vector3.ZERO
|
var _auth_walk_goal: Vector3 = Vector3.ZERO
|
||||||
|
|
@ -84,8 +85,25 @@ func _physics_process(_delta: float) -> void:
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Do not follow NavigationAgent3D waypoints: from the bump plateau the first segment often
|
# Waypoints route around obstacles; steering stays horizontal-only (see _steer_toward_world_point)
|
||||||
# drops straight down the mesh, and the agent map can disagree with presentation. Steer only
|
# so bump plateaus do not get a mostly-vertical first segment. If next waypoint aligns under the
|
||||||
# toward the server goal in xz; move_and_slide + floor handles slopes and obstacles.
|
# player (small xz delta), fall back to steering toward the goal xz.
|
||||||
_steer_toward_world_point(_auth_walk_goal)
|
var nav_map: RID = _nav_agent.get_navigation_map()
|
||||||
|
if NavigationServer3D.map_get_iteration_id(nav_map) == 0:
|
||||||
|
_steer_toward_world_point(_auth_walk_goal)
|
||||||
|
move_and_slide()
|
||||||
|
return
|
||||||
|
|
||||||
|
if horiz_dist <= DIRECT_APPROACH_RADIUS:
|
||||||
|
_steer_toward_world_point(_auth_walk_goal)
|
||||||
|
else:
|
||||||
|
var next_path_position: Vector3 = _nav_agent.get_next_path_position()
|
||||||
|
var to_next_h: Vector3 = Vector3(
|
||||||
|
next_path_position.x - global_position.x, 0.0, next_path_position.z - global_position.z
|
||||||
|
)
|
||||||
|
if to_next_h.length_squared() > 0.0025:
|
||||||
|
_steer_toward_world_point(next_path_position)
|
||||||
|
else:
|
||||||
|
_steer_toward_world_point(_auth_walk_goal)
|
||||||
|
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue