diff --git a/client/scenes/main.tscn b/client/scenes/main.tscn index a954d9e..395914c 100644 --- a/client/scenes/main.tscn +++ b/client/scenes/main.tscn @@ -33,6 +33,9 @@ size = Vector3(0.9, 1, 0.4) [sub_resource type="StandardMaterial3D" id="Mat_terminal"] 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"] 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"] geometry_parsed_geometry_type = 2 -geometry_collision_mask = 4294967295 +geometry_collision_mask = 1 geometry_source_geometry_mode = 0 cell_size = 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) 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) +collision_layer = 1 [node name="MeshInstance3D" type="MeshInstance3D" parent="World/NavigationRegion3D/PrototypeTerminal" unique_id=1700002] mesh = SubResource("BoxMesh_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] 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) 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) collision_layer = 2 collision_mask = 1 @@ -198,10 +205,10 @@ floor_snap_length = 0.28 safe_margin = 0.045 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") -[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 path_desired_distance = 0.35 target_desired_distance = 0.35 @@ -209,7 +216,7 @@ path_height_offset = 0.0 radius = 0.4 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") [node name="GroundPick" type="Node3D" parent="." unique_id=2500001] diff --git a/client/scripts/main.gd b/client/scripts/main.gd index e7b9bf2..6c8aaf1 100644 --- a/client/scripts/main.gd +++ b/client/scripts/main.gd @@ -11,7 +11,7 @@ var _move_reject_msg_token: int = 0 @onready var _camera: Camera3D = $World/Camera3D @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 _authority: Node = $PositionAuthorityClient @onready var _radius_preview: Node3D = $World/InteractionMarkers diff --git a/client/scripts/player.gd b/client/scripts/player.gd index 30b687d..0f90763 100644 --- a/client/scripts/player.gd +++ b/client/scripts/player.gd @@ -10,6 +10,7 @@ const ARRIVE_EPS: float = 0.35 const VERT_ARRIVE_EPS: float = 0.055 const MAX_CLIMB_SPEED: float = 2.6 const MAX_DESCENT_SPEED: float = 2.2 +const DIRECT_APPROACH_RADIUS: float = 0.85 var _has_walk_goal: bool = false var _auth_walk_goal: Vector3 = Vector3.ZERO @@ -84,8 +85,25 @@ func _physics_process(_delta: float) -> void: move_and_slide() return - # Do not follow NavigationAgent3D waypoints: from the bump plateau the first segment often - # drops straight down the mesh, and the agent map can disagree with presentation. Steer only - # toward the server goal in xz; move_and_slide + floor handles slopes and obstacles. - _steer_toward_world_point(_auth_walk_goal) + # Waypoints route around obstacles; steering stays horizontal-only (see _steer_toward_world_point) + # so bump plateaus do not get a mostly-vertical first segment. If next waypoint aligns under the + # player (small xz delta), fall back to steering toward the goal xz. + 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()