8462a2fde7
- Added SymptomManager autoload for managing symptom intensities. - Introduced nausea tilt effect for camera roll based on nausea intensity. - Created color desaturation shader and overlay for visual feedback. - Developed TreatmentManager to handle nausea ramping during IV treatment. - Added hospital room scene with first-person controller and interactions. - Implemented sit-down interaction for the treatment chair. - Created IV insertion sequence with animations and completion signal. - Added player controller with movement and interaction capabilities. - Integrated nausea effects into the player experience with smooth transitions.
78 lines
2.3 KiB
GDScript
78 lines
2.3 KiB
GDScript
class_name PlayerController
|
|
extends CharacterBody3D
|
|
## First-person player controller.
|
|
## WASD movement, mouse-look, gravity, and an interaction raycast.
|
|
|
|
@export var walk_speed: float = 4.0
|
|
@export var mouse_sensitivity: float = 0.0025
|
|
@export var pitch_limit_deg: float = 89.0
|
|
|
|
## When true, all movement and look input is ignored (e.g. while seated).
|
|
var movement_locked: bool = false
|
|
|
|
@onready var camera: Camera3D = $Camera3D
|
|
@onready var interaction_ray: RayCast3D = $Camera3D/InteractionRay
|
|
|
|
var _gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity", 9.8)
|
|
|
|
|
|
func _ready() -> void:
|
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if movement_locked:
|
|
return
|
|
|
|
# Mouse look.
|
|
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
|
rotate_y(-event.relative.x * mouse_sensitivity)
|
|
camera.rotate_x(-event.relative.y * mouse_sensitivity)
|
|
var limit := deg_to_rad(pitch_limit_deg)
|
|
camera.rotation.x = clampf(camera.rotation.x, -limit, limit)
|
|
|
|
# Release / recapture mouse with Escape (handy for alt-tab / debugging).
|
|
if event.is_action_pressed("ui_cancel"):
|
|
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
|
else:
|
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
# Gravity.
|
|
if not is_on_floor():
|
|
velocity.y -= _gravity * delta
|
|
|
|
if movement_locked:
|
|
velocity.x = 0.0
|
|
velocity.z = 0.0
|
|
move_and_slide()
|
|
return
|
|
|
|
# Horizontal movement from input.
|
|
var input_dir := Input.get_vector(
|
|
"move_left", "move_right", "move_forward", "move_back"
|
|
)
|
|
var direction := (transform.basis * Vector3(input_dir.x, 0.0, input_dir.y)).normalized()
|
|
if direction != Vector3.ZERO:
|
|
velocity.x = direction.x * walk_speed
|
|
velocity.z = direction.z * walk_speed
|
|
else:
|
|
velocity.x = move_toward(velocity.x, 0.0, walk_speed)
|
|
velocity.z = move_toward(velocity.z, 0.0, walk_speed)
|
|
|
|
move_and_slide()
|
|
|
|
|
|
## Returns the object currently under the interaction ray, or null.
|
|
func get_interaction_target() -> Object:
|
|
if interaction_ray and interaction_ray.is_colliding():
|
|
return interaction_ray.get_collider()
|
|
return null
|
|
|
|
|
|
## Lock or unlock player movement/look (used by sit-down and minigames).
|
|
func set_movement_locked(locked: bool) -> void:
|
|
movement_locked = locked
|