70 lines
2.1 KiB
GDScript
70 lines
2.1 KiB
GDScript
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
|