Browse Source

:wrench: Add a door to smooth walker entry

DricomDragon 2 months ago
parent
commit
c74c44e90c

+ 8 - 0
godot/component/entity/vehicles/biplan/biplan.gd

@@ -34,6 +34,14 @@ func get_free_seat() -> Node3D:
 	return $DrivingSeat
 
 
+func get_door() -> Node3D:
+	return $FrontRightDoor
+
+
+func get_closest_door(from: Vector3) -> Node3D:
+	return get_door()
+
+
 func _physics_process(_delta) -> void:
 	# Command part
 	_apply_plane_rotation()

+ 4 - 1
godot/component/entity/vehicles/biplan/biplan.tscn

@@ -86,9 +86,12 @@ shape = SubResource("BoxShape3D_6m175")
 transform = Transform3D(1, 0, 0, 0, 0.980604, -0.195998, 0, 0.195998, 0.980604, 0, 0.107529, -0.828761)
 shape = SubResource("BoxShape3D_6m175")
 
-[node name="DrivingSeat" type="Node3D" parent="." groups=["vehicle:seat"]]
+[node name="DrivingSeat" type="Marker3D" parent="." groups=["vehicle:seat"]]
 transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 2.38419e-07, 0.462769, -0.53054)
 
+[node name="FrontRightDoor" type="Marker3D" parent="." groups=["vehicle:door"]]
+transform = Transform3D(0.84102, 0, -0.541004, 0, 1, 0, 0.541004, 0, 0.84102, -1.53016, 0.397801, 0.712034)
+
 [node name="VerticalFoil" type="CollisionShape3D" parent="."]
 transform = Transform3D(1, 0, 0, 0, 0.823354, -0.567528, 0, 0.567528, 0.823354, -2.38419e-07, 0.989526, -3.4046)
 shape = SubResource("BoxShape3D_ws8bj")

+ 5 - 1
godot/component/entity/vehicles/jeep/Jeep.tscn

@@ -83,6 +83,10 @@ damping_relaxation = 0.5
 
 [node name="OrangeJeepOpen_wheel4" parent="RearRightWheel" instance=ExtResource("3_skal6")]
 
-[node name="RearSeat" type="Node3D" parent="." groups=["vehicle:seat"]]
+[node name="RearSeat" type="Marker3D" parent="." groups=["vehicle:seat"]]
 unique_name_in_owner = true
 transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0.495948, -0.178343)
+
+[node name="RightDoor" type="Marker3D" parent="." groups=["vehicle:door"]]
+unique_name_in_owner = true
+transform = Transform3D(-0.840567, 0, -0.541708, 0, 1, 0, 0.541708, 0, -0.840567, -0.821067, 0.693978, 0)

+ 8 - 0
godot/component/entity/vehicles/jeep/jeep.gd

@@ -25,6 +25,14 @@ func get_free_seat() -> Node3D:
 	return %RearSeat
 
 
+func get_door() -> Node3D:
+	return %RightDoor
+
+
+func get_closest_door(from: Vector3) -> Node3D:
+	return get_door()
+
+
 func drive_with(commander: LocalInput) -> void:
 	hand_brake(false)
 	super.drive_with(commander)

+ 8 - 0
godot/component/entity/vehicles/plane/tiny_plane.gd

@@ -29,6 +29,14 @@ func get_free_seat() -> Node3D:
 	return $DrivingSeat
 
 
+func get_door() -> Node3D:
+	return $UpDoor
+
+
+func get_closest_door(from: Vector3) -> Node3D:
+	return get_door()
+
+
 func _physics_process(_delta) -> void:
 	# Command part
 	_apply_plane_rotation()

+ 4 - 1
godot/component/entity/vehicles/plane/tiny_plane.tscn

@@ -36,5 +36,8 @@ shape = SubResource("BoxShape3D_w478f")
 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.192811, 0.0385618)
 shape = SubResource("BoxShape3D_stelr")
 
-[node name="DrivingSeat" type="Node3D" parent="." groups=["vehicle:seat"]]
+[node name="DrivingSeat" type="Marker3D" parent="." groups=["vehicle:seat"]]
 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.253056, -0.941579)
+
+[node name="UpDoor" type="Marker3D" parent="." groups=["vehicle:door"]]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.15208, -0.572886)

+ 11 - 1
godot/component/entity/vehicles/seated_vehicle.gd

@@ -39,7 +39,7 @@ func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
 
 
 func _on_body_shape_entered(_body_rid, body: Node, _body_shape_index, _local_shape_index) -> void:
-	if body is Walker:
+	if body.is_in_group("walker"):
 		return
 
 	_has_collided = true
@@ -56,6 +56,16 @@ func get_free_seat() -> Node3D:
 	return null
 
 
+## Need to be overridden to return an arbitrary door
+func get_door() -> Node3D:
+	return null
+
+
+## Need to be overridden to return the nearest door from local position
+func get_closest_door(from: Vector3) -> Node3D:
+	return null
+
+
 ## Need to be overridden to react to direction changed
 func _on_dir_changed(_dir: Vector2) -> void:
 	pass

+ 20 - 37
godot/component/entity/walker/walker.gd

@@ -17,16 +17,14 @@ signal chocolate_collected
 ## Vertical impulse applied to the character upon jumping in meters per second.
 @export var jump_impulse = 20
 
-@export_group("Seat", "seat_")
-@export var seat_min_dist: float = 0.0005
-@export var seat_access_speed: float = 2.0
-@export var seat_rotation_duration: float = 1.0
+@export_group("Boarding", "board_")
+@export var board_door_access_duration: float = 1.0
+@export var board_seat_access_duration: float = 0.5
 
 var target_velocity := Vector3.ZERO
 var target_character_direction := Vector3.ZERO # From command
 
-var _vehicle: Node3D = null
-var _seat: Node3D = null
+var _vehicle: SeatedVehicle = null
 var _can_get_in: bool = false
 
 @onready var _vehicle_range: RayCast3D = $VehicleRange
@@ -67,7 +65,7 @@ func get_pocket_position() -> Vector3:
 
 func _physics_process(delta: float) -> void:
 	if is_onboard():
-		_get_on_driver_seat()
+		pass # Nothing
 	else:
 		_move_with_feet(delta)
 		_signal_when_can_get_in()
@@ -103,21 +101,6 @@ func _signal_when_can_get_in() -> void:
 		_can_get_in = can_get_in_now
 
 
-func _get_on_driver_seat() -> void:
-	if _seat == null :
-		return
-
-	if position.distance_squared_to(_seat.position) < seat_min_dist:
-		return
-
-	var rotation_tween: Tween = create_tween()
-	rotation_tween.tween_property(self, "quaternion", _seat.quaternion, seat_rotation_duration)
-
-	var local_velocity = (_seat.position - position).normalized() * seat_access_speed
-	velocity = get_parent().get_transform().basis * local_velocity
-	move_and_slide()
-
-
 func _on_dir_changed(dir: Vector2) -> void:
 	if is_onboard():
 		return
@@ -144,7 +127,7 @@ func _on_get_in_action(commander: LocalInput) -> void:
 ## and get in to it
 ## and take the wheel !
 func _get_in_vehicle(commander: LocalInput) -> void:
-	var closest_vehicle: Node3D = _get_closest_vehicle()
+	var closest_vehicle: SeatedVehicle = _get_closest_vehicle()
 
 	if closest_vehicle == null:
 		return # No vehicle to get inside
@@ -153,7 +136,7 @@ func _get_in_vehicle(commander: LocalInput) -> void:
 	reparent(_vehicle)
 	add_collision_exception_with(_vehicle)
 	_vehicle.drive_with(commander)
-	_seat = _find_seat_on(_vehicle)
+	_move_to_seat(_vehicle)
 	got_in.emit(_vehicle)
 
 
@@ -163,7 +146,6 @@ func _get_out_vehicle() -> void:
 	remove_collision_exception_with(_vehicle)
 	reparent(_vehicle.get_parent())
 	_vehicle = null
-	_seat = null
 	_get_head_up()
 	got_out.emit()
 
@@ -184,24 +166,25 @@ func _look_forward(forward: Vector3) -> void:
 
 ## Return closest vehicle within reach
 ## or null if there are none
-func _get_closest_vehicle() -> Node3D:
+func _get_closest_vehicle() -> SeatedVehicle:
 	_vehicle_range.force_raycast_update()
 
 	var object_within_range: Object = _vehicle_range.get_collider()
 
-	if object_within_range is Node3D:
-		var node_within_range: Node3D = object_within_range as Node3D
-
-		if node_within_range.is_in_group("vehicle"):
-			return node_within_range
+	if object_within_range is SeatedVehicle:
+		return object_within_range as SeatedVehicle
 
 	return null
 
 
-## Have a seat on the driven vehicle if a seat
-## is available
-func _find_seat_on(vehicule: Node3D) -> Node3D:
-	if vehicule.has_method("get_free_seat") :
-		return vehicule.get_free_seat()
+## Move gently to a free seat from the nearest door
+func _move_to_seat(vehicule: SeatedVehicle) -> void:
+	var tween: Tween = create_tween()
 
-	return null
+	var door: Node3D = vehicule.get_closest_door(get_position())
+	tween.tween_property(self, "position", door.get_position(), board_door_access_duration)
+	tween.parallel().tween_property(self, "quaternion", door.get_quaternion(), board_door_access_duration)
+
+	var seat: Node3D = vehicule.get_free_seat()
+	tween.tween_property(self, "position", seat.get_position(), board_seat_access_duration)
+	tween.parallel().tween_property(self, "quaternion", seat.get_quaternion(), board_seat_access_duration)

+ 1 - 1
godot/component/entity/walker/walker.tscn

@@ -6,7 +6,7 @@
 [sub_resource type="BoxShape3D" id="BoxShape3D_6q2sk"]
 size = Vector3(0.56, 0.8, 0.4)
 
-[node name="Walker" type="CharacterBody3D"]
+[node name="Walker" type="CharacterBody3D" groups=["walker"]]
 collision_layer = 2
 collision_mask = 29
 script = ExtResource("1_xg6by")

+ 2 - 0
godot/project.godot

@@ -31,6 +31,8 @@ enabled=PackedStringArray("res://addons/input_prompts/plugin.cfg")
 
 vehicle="An technical object that the player can drive"
 vehicle:seat="A place on a vehicle where the player can sit on"
+vehicle:door="A temporary location the play go through to get in or out a vehicle"
+walker="A character that moves with feet"
 
 [input]