extends Node class_name State @export var state_id: StringName = &"" @export var next_state_id: StringName @export var random_next_state_ids: Array[StringName] = [] @export var animation_name: String @export var exit_on_action_finished: bool @export var exit_on_animation_finished: bool @export var min_wait_time: float = 3.0 @export var max_wait_time: float = 10 var runtime_timer: Timer @onready var agent: AIBase = owner signal transitioned(state: State, new_state_id: StringName) func _ready() -> void: if min_wait_time > 0 and !exit_on_action_finished: runtime_timer = Timer.new() runtime_timer.name = "IdleTimer" runtime_timer.one_shot = true add_child(runtime_timer) runtime_timer.timeout.connect(_on_timer_timeout) func enter() -> void: if exit_on_animation_finished: if not agent.anim_player.animation_finished.is_connected(_on_animation_finished): agent.anim_player.animation_finished.connect(_on_animation_finished) elif min_wait_time > 0 and !exit_on_action_finished: var wait_time:= randf_range(min_wait_time, max_wait_time) runtime_timer.start(wait_time) func exit() -> void: if exit_on_animation_finished and agent.anim_player.animation_finished.is_connected(_on_animation_finished): agent.anim_player.animation_finished.disconnect(_on_animation_finished) if runtime_timer and not runtime_timer.is_stopped(): runtime_timer.stop() func update(_delta: float) -> void: pass func physics_update(_delta: float) -> void: pass func run_animation() -> void: if agent.anim_player and agent.anim_player.has_animation(animation_name): agent.anim_player.play(animation_name) func _on_animation_finished(anim_name: StringName) -> void: if animation_name == anim_name: if exit_on_action_finished: return elif min_wait_time > 0: var wait_time := randf_range(min_wait_time, max_wait_time) runtime_timer.start(wait_time) else: transitioned.emit(self, get_next_state()) func _on_timer_timeout() -> void: transitioned.emit(self, get_next_state()) func get_next_state() -> StringName: if random_next_state_ids.size() > 0: return random_next_state_ids.pick_random() return next_state_id