From 0c237430eaa5cd33dd4647fcfee822eeb4cc2079 Mon Sep 17 00:00:00 2001 From: "m.cirafisi" Date: Fri, 22 May 2026 00:06:23 +0200 Subject: [PATCH] ai refactoring --- core/ai/agents/base/ai_base.gd | 22 +++------------ core/ai/agents/base/ai_base.tscn | 13 +-------- core/ai/agents/base/idle_state.gd | 7 ++--- core/ai/agents/base/patrol_state.gd | 8 ++---- core/ai/agents/human/ai_citizen.tscn | 7 +++-- core/ai/agents/human/ai_citizen_sitter.tscn | 7 +++++ core/ai/agents/human/ai_citizen_walker.tscn | 24 +++++++++++++++++ core/ai/agents/human/ai_farmer.tscn | 7 +++++ core/ai/framework/state.gd | 10 +++++++ docs/gyms/ai/gym_ai.tscn | 30 ++++----------------- 10 files changed, 67 insertions(+), 68 deletions(-) create mode 100644 core/ai/agents/human/ai_citizen_sitter.tscn create mode 100644 core/ai/agents/human/ai_citizen_walker.tscn create mode 100644 core/ai/agents/human/ai_farmer.tscn diff --git a/core/ai/agents/base/ai_base.gd b/core/ai/agents/base/ai_base.gd index 2d40379..05718bb 100644 --- a/core/ai/agents/base/ai_base.gd +++ b/core/ai/agents/base/ai_base.gd @@ -2,7 +2,7 @@ extends CharacterBody3D class_name AIBase -@export_group("Movement") +@export_group("Settings") @export var speed: float = 4.0 var _enable_state_machine: bool = true @export var enable_state_machine: bool: @@ -11,13 +11,8 @@ var _enable_state_machine: bool = true toggle_enable_state_machine() get: return _enable_state_machine - @export var anim_player: AnimationPlayer -@onready var patrol_radius_shape: CollisionShape3D = $%PatrolRadiusShape -@onready var nav_agent: NavigationAgent3D = $%NavigationAgent3D -@onready var state_machine: StateMachine = $%StateMachine - @export_group("Entities") enum EntityType { HUMANOID, ANIMAL } @export var entity_type: EntityType = EntityType.HUMANOID @@ -25,6 +20,9 @@ enum EntityType { HUMANOID, ANIMAL } @export var allowed_biomes: Array[String] = [] @export_range(0.0, 100.0, 0.1) var spawn_uniqueness: float = 1.0 +@onready var patrol_radius_shape: CollisionShape3D = $%PatrolRadiusShape +@onready var nav_agent: NavigationAgent3D = $%NavigationAgent3D +@onready var state_machine: StateMachine = $%StateMachine func _ready() -> void: randomize() @@ -63,15 +61,3 @@ func navigate_to_random_point() -> void: var target_point_in_space = global_position + Vector3(randf_range(-1, 1), 0, randf_range(-1, 1)).normalized() * randf_range(0, patrol_radius) var closest_valid_point = NavigationServer3D.map_get_closest_point(nav_map_rid, target_point_in_space) nav_agent.target_position = closest_valid_point - -func run_walking_animation() -> void: - if anim_player and anim_player.has_animation("custom/walking"): - var anim = anim_player.get_animation("custom/walking") - anim.loop_mode = Animation.LOOP_LINEAR - anim_player.play("custom/walking") - -func run_idle_animation() -> void: - if anim_player and anim_player.has_animation("custom/idle"): - var anim = anim_player.get_animation("custom/idle") - anim.loop_mode = Animation.LOOP_LINEAR - anim_player.play("custom/idle") diff --git a/core/ai/agents/base/ai_base.tscn b/core/ai/agents/base/ai_base.tscn index 44e4e51..3782ad6 100644 --- a/core/ai/agents/base/ai_base.tscn +++ b/core/ai/agents/base/ai_base.tscn @@ -2,8 +2,6 @@ [ext_resource type="Script" uid="uid://b30p1yqojbbbk" path="res://core/ai/agents/base/ai_base.gd" id="1_4d1nn"] [ext_resource type="Script" uid="uid://ps3vlu2qvmop" path="res://core/ai/framework/state_machine.gd" id="2_q1hg3"] -[ext_resource type="Script" uid="uid://nga8qx56iwgu" path="res://core/ai/agents/base/idle_state.gd" id="3_26faq"] -[ext_resource type="Script" uid="uid://bngfthvt04ivv" path="res://core/ai/agents/base/patrol_state.gd" id="4_lim44"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_mh3lg"] @@ -25,18 +23,9 @@ shape = SubResource("CapsuleShape3D_mh3lg") [node name="NavigationAgent3D" type="NavigationAgent3D" parent="." unique_id=1370024449] unique_name_in_owner = true -[node name="StateMachine" type="Node" parent="." unique_id=1286404264 node_paths=PackedStringArray("initial_state")] +[node name="StateMachine" type="Node" parent="." unique_id=1286404264] unique_name_in_owner = true script = ExtResource("2_q1hg3") -initial_state = NodePath("IdleState") - -[node name="IdleState" type="Node" parent="StateMachine" unique_id=763668255] -script = ExtResource("3_26faq") -state_id = &"idle" - -[node name="PatrolState" type="Node" parent="StateMachine" unique_id=2054606629] -script = ExtResource("4_lim44") -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 95cf222..9bf8583 100644 --- a/core/ai/agents/base/idle_state.gd +++ b/core/ai/agents/base/idle_state.gd @@ -1,14 +1,11 @@ extends State -const PATROL_STATE_ID: StringName = &"patrol" - -@onready var agent: AIBase = owner @export var wait_time: float = 3.0 var runtime_timer: Timer func enter() -> void: - agent.run_idle_animation() + run_animation() runtime_timer = Timer.new() runtime_timer.name = "IdleTimer" add_child(runtime_timer) @@ -25,4 +22,4 @@ func exit() -> void: runtime_timer = null func _on_timer_timeout() -> void: - transitioned.emit(self, PATROL_STATE_ID) + transitioned.emit(self, next_state_id) diff --git a/core/ai/agents/base/patrol_state.gd b/core/ai/agents/base/patrol_state.gd index 6aa7786..61c50f2 100644 --- a/core/ai/agents/base/patrol_state.gd +++ b/core/ai/agents/base/patrol_state.gd @@ -1,13 +1,9 @@ extends State -const IDLE_STATE_ID: StringName = &"idle" - -@onready var agent: AIBase = owner - func enter() -> void: + run_animation() agent.navigate_to_random_point() - agent.run_walking_animation() func physics_update(_delta) -> void: if agent.nav_agent.is_navigation_finished(): - transitioned.emit(self, IDLE_STATE_ID) + transitioned.emit(self, next_state_id) diff --git a/core/ai/agents/human/ai_citizen.tscn b/core/ai/agents/human/ai_citizen.tscn index 9fc11e6..629afb4 100644 --- a/core/ai/agents/human/ai_citizen.tscn +++ b/core/ai/agents/human/ai_citizen.tscn @@ -1,7 +1,10 @@ [gd_scene format=3 uid="uid://bdqeshcwwnyc4"] -[ext_resource type="PackedScene" uid="uid://mvh2v6v72stt" path="res://core/ai/agents/human/ai_human.tscn" id="1_yh31u"] +[ext_resource type="PackedScene" uid="uid://mvh2v6v72stt" path="res://core/ai/agents/human/ai_human.tscn" id="1_awhwq"] -[node name="AiCitizen" unique_id=1228675528 instance=ExtResource("1_yh31u")] +[node name="AiCitizen" unique_id=1228675528 instance=ExtResource("1_awhwq")] + +[node name="StateMachine" parent="." index="3" unique_id=1286404264 node_paths=PackedStringArray("initial_state")] +initial_state = NodePath("") [editable path="HumanMannequin"] diff --git a/core/ai/agents/human/ai_citizen_sitter.tscn b/core/ai/agents/human/ai_citizen_sitter.tscn new file mode 100644 index 0000000..9289b97 --- /dev/null +++ b/core/ai/agents/human/ai_citizen_sitter.tscn @@ -0,0 +1,7 @@ +[gd_scene format=3 uid="uid://bbseno7clbepx"] + +[ext_resource type="PackedScene" uid="uid://bdqeshcwwnyc4" path="res://core/ai/agents/human/ai_citizen.tscn" id="1_cduuu"] + +[node name="AiCitizenSitter" unique_id=1228675528 instance=ExtResource("1_cduuu")] + +[editable path="HumanMannequin"] diff --git a/core/ai/agents/human/ai_citizen_walker.tscn b/core/ai/agents/human/ai_citizen_walker.tscn new file mode 100644 index 0000000..7ce0ff5 --- /dev/null +++ b/core/ai/agents/human/ai_citizen_walker.tscn @@ -0,0 +1,24 @@ +[gd_scene format=3 uid="uid://bnnuke5e7e1yr"] + +[ext_resource type="PackedScene" uid="uid://bdqeshcwwnyc4" path="res://core/ai/agents/human/ai_citizen.tscn" id="1_dms8s"] +[ext_resource type="Script" uid="uid://nga8qx56iwgu" path="res://core/ai/agents/base/idle_state.gd" id="2_tiuwx"] +[ext_resource type="Script" uid="uid://bngfthvt04ivv" path="res://core/ai/agents/base/patrol_state.gd" id="3_8d0tj"] + +[node name="AiCitizenWalker" unique_id=1228675528 instance=ExtResource("1_dms8s")] + +[node name="StateMachine" parent="." index="3" unique_id=1286404264 node_paths=PackedStringArray("initial_state")] +initial_state = NodePath("IdleState") + +[node name="IdleState" type="Node" parent="StateMachine" index="0" unique_id=42226979] +script = ExtResource("2_tiuwx") +state_id = &"idle" +next_state_id = &"patrol" +animation_name = "custom/idle" + +[node name="PatrolState" type="Node" parent="StateMachine" index="1" unique_id=1357892786] +script = ExtResource("3_8d0tj") +state_id = &"patrol" +next_state_id = &"idle" +animation_name = "custom/walking" + +[editable path="HumanMannequin"] diff --git a/core/ai/agents/human/ai_farmer.tscn b/core/ai/agents/human/ai_farmer.tscn new file mode 100644 index 0000000..c074915 --- /dev/null +++ b/core/ai/agents/human/ai_farmer.tscn @@ -0,0 +1,7 @@ +[gd_scene format=3 uid="uid://ceqxsqfiotm5j"] + +[ext_resource type="PackedScene" uid="uid://mvh2v6v72stt" path="res://core/ai/agents/human/ai_human.tscn" id="1_l2y7m"] + +[node name="AiFarmer" unique_id=1228675528 instance=ExtResource("1_l2y7m")] + +[editable path="HumanMannequin"] diff --git a/core/ai/framework/state.gd b/core/ai/framework/state.gd index b24ae72..1c35add 100644 --- a/core/ai/framework/state.gd +++ b/core/ai/framework/state.gd @@ -3,6 +3,10 @@ extends Node class_name State @export var state_id: StringName = &"" +@export var next_state_id: StringName +@export var animation_name: String + +@onready var agent: AIBase = owner @warning_ignore("unused_signal") signal transitioned(state: State, new_state_id: StringName) @@ -18,3 +22,9 @@ func update(_delta) -> void: func physics_update(_delta) -> void: pass + +func run_animation() -> void: + if agent.anim_player and agent.anim_player.has_animation(animation_name): + var anim = agent.anim_player.get_animation(animation_name) + anim.loop_mode = Animation.LOOP_LINEAR + agent.anim_player.play(animation_name) diff --git a/docs/gyms/ai/gym_ai.tscn b/docs/gyms/ai/gym_ai.tscn index d457b8d..2fb9408 100644 --- a/docs/gyms/ai/gym_ai.tscn +++ b/docs/gyms/ai/gym_ai.tscn @@ -1,11 +1,6 @@ [gd_scene format=3 uid="uid://dqvrhiqgkd3w1"] -[ext_resource type="PackedScene" uid="uid://dd8wn62anbts8" path="res://core/ai/agents/cow/ai_cow.tscn" id="2_fdj8t"] -[ext_resource type="PackedScene" uid="uid://mvh2v6v72stt" path="res://core/ai/agents/human/ai_human.tscn" id="2_n3ssi"] -[ext_resource type="PackedScene" uid="uid://cayakdk7gmlyg" path="res://core/ai/agents/horse/ai_horse.tscn" id="3_fdj8t"] -[ext_resource type="PackedScene" uid="uid://c2hg6hu2y5srb" path="res://core/ai/agents/pig/ai_pig.tscn" id="4_fj3qp"] -[ext_resource type="PackedScene" uid="uid://2md4l83fy8kr" path="res://core/ai/agents/pug/ai_pug.tscn" id="5_a3kkd"] -[ext_resource type="PackedScene" uid="uid://bs1bdtm7jdtgb" path="res://core/ai/agents/sheep/ai_sheep.tscn" id="6_uj4wt"] +[ext_resource type="PackedScene" uid="uid://bnnuke5e7e1yr" path="res://core/ai/agents/human/ai_citizen_walker.tscn" id="1_a2xtd"] [sub_resource type="NavigationMesh" id="NavigationMesh_optuv"] vertices = PackedVector3Array(10.984741, 0.25012434, -1.0140381, 11.234741, 0.25012434, 0.23596191, 19.484741, 0.25012434, 0.23596191, 19.484741, 0.25012434, -19.514038, 9.234741, 0.25012434, -1.0140381, -19.515259, 0.25012434, -19.514038, -19.515259, 0.25012434, -0.014038086, 8.984741, 0.25012434, -0.014038086, 10.984741, 0.25012434, 1.2359619, 19.484741, 0.25012434, 19.235962, 9.234741, 0.25012434, 1.2359619, -19.515259, 0.25012434, 19.235962) @@ -90,23 +85,8 @@ Parameters: - Area Radius: Radius of the SphereShape3D used by PatrolRadiusShape." autowrap_mode = 2 -[node name="AiBase" parent="." unique_id=1166354984 instance=ExtResource("2_n3ssi")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.30116, 0.94226456, 6.322365) +[node name="AiCitizenWalker" parent="." unique_id=1228675528 instance=ExtResource("1_a2xtd")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 1, -6) -[node name="Camera3D" type="Camera3D" parent="." unique_id=1148396057] -transform = Transform3D(-2.0613477e-08, 0.8818225, -0.47158146, 3.854569e-08, 0.47158146, 0.8818225, 1, -3.5527137e-15, -4.371139e-08, -17.32454, 16.344711, 0) - -[node name="AiCow" parent="." unique_id=1228675528 instance=ExtResource("2_fdj8t")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.127514, 0.94226265, -6.1312685) - -[node name="AiHorse" parent="." unique_id=2103173512 instance=ExtResource("3_fdj8t")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.0360618, 0.94226265, 2.8466864) - -[node name="AiPig" parent="." unique_id=1737929442 instance=ExtResource("4_fj3qp")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 1, -2) - -[node name="AiPug" parent="." unique_id=1080338869 instance=ExtResource("5_a3kkd")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.2930422, 0.9422636, 6.726594) - -[node name="AiSheep" parent="." unique_id=1308433233 instance=ExtResource("6_uj4wt")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.684046, 0.7251625, -7.7062917) +[node name="Camera3D" type="Camera3D" parent="." unique_id=1753000680] +transform = Transform3D(1, 0, 0, 0, 0.42261824, 0.9063078, 0, -0.9063078, 0.42261824, 0, 18.361065, 15.377485)