From a51e94d4d30bf768a429371482665c4302fdd9b2 Mon Sep 17 00:00:00 2001 From: "m.cirafisi" Date: Thu, 16 Apr 2026 15:51:10 +0200 Subject: [PATCH] update AI and doc --- core/ai/agents/base/ai_base.gd | 11 +++-- core/ai/agents/base/ai_base.tscn | 4 +- core/ai/agents/base/idle_state.gd | 4 +- core/ai/agents/base/patrol_state.gd | 6 ++- core/ai/framework/state.gd | 4 +- core/ai/framework/state_machine.gd | 43 +++++++++++++------ docs/museums/ai/museum_ai.tscn | 20 ++++----- .../museums/photo_mode/museum_photo_mode.tscn | 13 +++--- docs/museums/radio/museum_radio.tscn | 4 +- 9 files changed, 66 insertions(+), 43 deletions(-) diff --git a/core/ai/agents/base/ai_base.gd b/core/ai/agents/base/ai_base.gd index f75d9d8..96dcc0d 100644 --- a/core/ai/agents/base/ai_base.gd +++ b/core/ai/agents/base/ai_base.gd @@ -3,10 +3,13 @@ extends CharacterBody3D class_name AIBase @export var speed: float = 4.0 -@export var enable_state_machine: bool = true: +var _enable_state_machine: bool = true +@export var enable_state_machine: bool: set(value): - enable_state_machine = value + _enable_state_machine = value toggle_enable_state_machine() + get: + return _enable_state_machine @onready var patrol_radius_shape: CollisionShape3D = $%PatrolRadiusShape @@ -19,10 +22,10 @@ func _ready() -> void: toggle_enable_state_machine() func toggle_enable_state_machine() -> void: - state_machine.enable = enable_state_machine + state_machine.enable = _enable_state_machine func _physics_process(delta: float) -> void: - if !enable_state_machine: + if !_enable_state_machine: return state_machine.physics_process(delta) diff --git a/core/ai/agents/base/ai_base.tscn b/core/ai/agents/base/ai_base.tscn index cc17d5c..2143094 100644 --- a/core/ai/agents/base/ai_base.tscn +++ b/core/ai/agents/base/ai_base.tscn @@ -31,11 +31,11 @@ initial_state = NodePath("IdleState") [node name="IdleState" type="Node" parent="StateMachine" unique_id=763668255] script = ExtResource("3_26faq") -state_id = "idle" +state_id = &"idle" [node name="PatrolState" type="Node" parent="StateMachine" unique_id=2054606629] script = ExtResource("4_lim44") -state_id = "patrol" +state_id = &"patrol" [node name="PatrolRadiusShape" type="CollisionShape3D" parent="." unique_id=1379515938] unique_name_in_owner = true diff --git a/core/ai/agents/base/idle_state.gd b/core/ai/agents/base/idle_state.gd index fb9d45e..8e5062b 100644 --- a/core/ai/agents/base/idle_state.gd +++ b/core/ai/agents/base/idle_state.gd @@ -1,5 +1,7 @@ extends State +const PATROL_STATE_ID: StringName = &"patrol" + @export var wait_time: float = 3.0 var runtime_timer: Timer @@ -21,4 +23,4 @@ func exit() -> void: runtime_timer = null func _on_timer_timeout() -> void: - transitioned.emit(self, "patrol") + transitioned.emit(self, PATROL_STATE_ID) diff --git a/core/ai/agents/base/patrol_state.gd b/core/ai/agents/base/patrol_state.gd index 9db0692..0a1fdd7 100644 --- a/core/ai/agents/base/patrol_state.gd +++ b/core/ai/agents/base/patrol_state.gd @@ -1,10 +1,12 @@ extends State +const IDLE_STATE_ID: StringName = &"idle" + @onready var agent: AIBase = owner func enter() -> void: agent.navigate_to_random_point() -func update(_delta) -> void: +func physics_update(_delta) -> void: if agent.nav_agent.is_navigation_finished(): - transitioned.emit(self, "idle") + transitioned.emit(self, IDLE_STATE_ID) diff --git a/core/ai/framework/state.gd b/core/ai/framework/state.gd index e3f8382..b24ae72 100644 --- a/core/ai/framework/state.gd +++ b/core/ai/framework/state.gd @@ -2,10 +2,10 @@ extends Node class_name State -@export var state_id: String = "" +@export var state_id: StringName = &"" @warning_ignore("unused_signal") -signal transitioned(state, new_state_name) +signal transitioned(state: State, new_state_id: StringName) func enter() -> void: pass diff --git a/core/ai/framework/state_machine.gd b/core/ai/framework/state_machine.gd index 7ae194b..0a91f3d 100644 --- a/core/ai/framework/state_machine.gd +++ b/core/ai/framework/state_machine.gd @@ -5,33 +5,48 @@ class_name StateMachine @export var initial_state: State var current_state: State -var states: Dictionary = {} -var enable: bool = true: +var states: Dictionary[StringName, State] = {} +var is_initialized: bool = false +var _enabled: bool = true +var enable: bool: set(value): - enable = value - toggle_enable() + _enabled = value + _set_enabled(value) + get: + return _enabled -func toggle_enable() -> void: - if !enable: - return - - if !states.is_empty(): +func _ready() -> void: + _initialize_states() + _set_enabled(enable) + +func _initialize_states() -> void: + if is_initialized: return for state in get_children(): if state is State: states[state.state_id] = state state.transitioned.connect(_on_state_transition) - - if initial_state: + + is_initialized = true + +func _set_enabled(value: bool) -> void: + _enabled = value + + if not _enabled: + return + + _initialize_states() + + if initial_state and current_state == null: current_state = initial_state current_state.enter() func physics_process(delta) -> void: - if current_state and enable: - current_state.update(delta) + if current_state and _enabled: + current_state.physics_update(delta) -func _on_state_transition(state: State, new_state_id: String) -> void: +func _on_state_transition(state: State, new_state_id: StringName) -> void: if state != current_state: return diff --git a/docs/museums/ai/museum_ai.tscn b/docs/museums/ai/museum_ai.tscn index b9a5a79..08f2c85 100644 --- a/docs/museums/ai/museum_ai.tscn +++ b/docs/museums/ai/museum_ai.tscn @@ -73,20 +73,20 @@ custom_minimum_size = Vector2(1, 1) layout_mode = 2 size_flags_vertical = 1 text = "System Logic: -- The NPC is based on CharacterBody3D and is managed via a Finite State Machine (FSM). -- Movement and navigation are calculated during the _physics_process. +- The NPC uses a finite state machine to switch between behaviors. +- State logic runs during physics updates, while movement is handled by the agent through NavigationAgent3D. AI States: -- IdleState: The agent remains stationary for the duration defined by the wait_time variable. -- PatrolState: The agent calculates a valid random point and moves toward it. +- IdleState: The agent waits in place for the duration defined by wait_time. +- PatrolState: The agent selects a valid random destination and moves toward it. Core Components: -- NavigationAgent3D: Manages pathfinding and detects when the agent reaches its destination. -- PatrolRadiusShape: Defines the radius of the area where the agent can move randomly. -- StateMachine: Coordinates transitions between states, such as the automatic switch from Idle to Patrol. +- NavigationAgent3D: Calculates the path and reports when the destination has been reached. +- PatrolRadiusShape: Defines the random movement area used when choosing the next patrol point. +- StateMachine: Initializes the available states and handles transitions between them. -Parameters: +Parameters: - Speed: Movement speed of the agent. -- Wait Time: Delay in seconds within the IdleState node. -- Area Radius: Size of the SphereShape3D inside the PatrolRadiusShape node." +- Wait Time: Delay in seconds on the IdleState node. +- Area Radius: Radius of the SphereShape3D used by PatrolRadiusShape." autowrap_mode = 2 diff --git a/docs/museums/photo_mode/museum_photo_mode.tscn b/docs/museums/photo_mode/museum_photo_mode.tscn index 27b4ea9..aaa55b4 100644 --- a/docs/museums/photo_mode/museum_photo_mode.tscn +++ b/docs/museums/photo_mode/museum_photo_mode.tscn @@ -112,20 +112,21 @@ size_flags_horizontal = 3 text = "System Logic: - The system allows players to toggle a free camera mode to photograph and collect museum items. - Game Pause: Activating the mode pauses the SceneTree, freezing the world while allowing the camera to remain functional. -- It uses a raycasting check to verify if a collectible is visible and unobstructed before unlocking it. -- The CollectionManager acts as a global singleton to track unlocked IDs and manage the library data. -- Save Collectibles and Photo +- Taking a photo saves the captured image to disk and checks which collectibles are visible and unobstructed before unlocking them. +- CollectionManager acts as a global singleton that tracks unlocked collectibles, saved photos, and the data used by the UI. Photo Mode Actions: - Toggle Mode(P): Switches between normal gameplay and the photo camera, capturing or releasing the mouse, and toggles the global pause state. -- Orbit & Pan(Mouse): The camera rotates around a target and can be panned horizontally or vertically. -- Capture(F): Performs a frustum check and a raycast to identify the target in view. +- Rotate(Mouse): The camera orbits around the configured target while photo mode is active. +- Pan(Input Actions): The camera can be moved horizontally and vertically within the configured bounds. +- Capture(F): Saves the current frame and performs frustum and raycast checks against collectibles in view. Core Components: - PhotoModeController: Manages camera inputs, movement logic, and the photo-taking process. - Collectible: An Area3D node placed on objects to make them identifiable by the camera. - CollectionManager: Handles the logic for unlocking items and provides data to the UI. -- CollectionCompendium: A UI grid that displays all items and visually highlights unlocked ones. +- CollectibleGallery: Displays all collectibles and visually highlights the unlocked ones. +- PhotoGallery: Displays the photos saved by the player during the session. Parameters: - Pan & Rotation Speed: Defines how fast the camera moves and rotates. diff --git a/docs/museums/radio/museum_radio.tscn b/docs/museums/radio/museum_radio.tscn index 02c24da..f45abba 100644 --- a/docs/museums/radio/museum_radio.tscn +++ b/docs/museums/radio/museum_radio.tscn @@ -85,6 +85,7 @@ Core Functionality: - Playlist Management: Stores a list of AudioStream resources and tracks the current song index. - Track Navigation: Allows cycling forward and backward through the playlist with index wrapping (loops back to start/end). - Playback Control: Supports jumping to specific tracks, toggling the pause state, and stopping the stream. +- Audio Settings: If the Music bus exists, the Settings menu can be used to test and adjust playback volume. Key Methods: - play_track: Loads a specific stream from the playlist and begins playback. @@ -92,8 +93,7 @@ Key Methods: - toggle_pause: Resumes or pauses the current stream without resetting its position. Adjustable Parameters: -- Playlist: An Array in the inspector where you can assign multiple AudioStream resources (e.g., .mp3, .ogg). -- Current Track Index: Determines which song starts playing by default." +- Playlist: An Array in the inspector where you can assign one or more AudioStream resources." autowrap_mode = 2 [connection signal="pressed" from="Control/VBoxContainer2/VBoxContainer/Button_Play" to="." method="_on_button_play_pressed"]