improve and update ai
This commit was merged in pull request #32.
This commit is contained in:
64
core/ai/framework/fly_away_state.gd
Normal file
64
core/ai/framework/fly_away_state.gd
Normal file
@@ -0,0 +1,64 @@
|
||||
extends State
|
||||
|
||||
class_name FlyAwayState
|
||||
|
||||
@export var fly_speed: float = 6.0
|
||||
@export var fly_up_speed: float = 3.0
|
||||
@export var destroy_after_seconds: float = 8.0
|
||||
|
||||
var _timer: float = 0.0
|
||||
var _fly_direction: Vector3 = Vector3.UP
|
||||
|
||||
func enter() -> void:
|
||||
super.enter()
|
||||
run_animation()
|
||||
|
||||
# Disable NavigationAgent3D influence since we want manual flight
|
||||
agent.nav_agent.process_mode = Node.PROCESS_MODE_DISABLED
|
||||
|
||||
var weather_nodes = get_tree().get_nodes_in_group("weather_node")
|
||||
var train_node = null
|
||||
for node in weather_nodes:
|
||||
if "Treno" in node.name or "Train" in node.name:
|
||||
train_node = node
|
||||
break
|
||||
|
||||
if not train_node:
|
||||
var train = get_tree().root.find_child("*Treno*", true, false)
|
||||
if train and train is Node3D:
|
||||
train_node = train
|
||||
else:
|
||||
train = get_tree().root.find_child("*Train*", true, false)
|
||||
if train and train is Node3D:
|
||||
train_node = train
|
||||
|
||||
if train_node:
|
||||
# Fly away from the train
|
||||
var dir_to_train = agent.global_position.direction_to(train_node.global_position)
|
||||
dir_to_train.y = 0
|
||||
if dir_to_train.length() > 0.1:
|
||||
_fly_direction = -dir_to_train.normalized()
|
||||
else:
|
||||
_fly_direction = -agent.global_transform.basis.z.normalized()
|
||||
else:
|
||||
# If no train found, just fly forward relative to current facing
|
||||
_fly_direction = -agent.global_transform.basis.z.normalized()
|
||||
|
||||
func physics_update(delta: float) -> void:
|
||||
_timer += delta
|
||||
if _timer >= destroy_after_seconds:
|
||||
agent.queue_free()
|
||||
return
|
||||
|
||||
var horizontal_vel = _fly_direction * fly_speed
|
||||
agent.velocity.x = horizontal_vel.x
|
||||
agent.velocity.y = fly_up_speed
|
||||
agent.velocity.z = horizontal_vel.z
|
||||
|
||||
# Rotate agent to face flight direction
|
||||
if horizontal_vel.length_squared() > 0.1:
|
||||
var look_dir = Vector3(agent.velocity.x, 0, agent.velocity.z)
|
||||
var target_transform = agent.global_transform.looking_at(agent.global_position - look_dir, Vector3.UP)
|
||||
agent.global_transform = agent.global_transform.interpolate_with(target_transform, delta * 5.0)
|
||||
|
||||
agent.move_and_slide()
|
||||
1
core/ai/framework/fly_away_state.gd.uid
Normal file
1
core/ai/framework/fly_away_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://tys4fmqvneom
|
||||
@@ -7,4 +7,6 @@ func enter() -> void:
|
||||
|
||||
func physics_update(_delta) -> void:
|
||||
if agent.nav_agent.is_navigation_finished():
|
||||
transitioned.emit(self, next_state_id)
|
||||
transitioned.emit(self, get_next_state())
|
||||
elif agent.nav_agent.get_current_navigation_path().is_empty():
|
||||
transitioned.emit(self, get_next_state())
|
||||
|
||||
18
core/ai/framework/run_state.gd
Normal file
18
core/ai/framework/run_state.gd
Normal file
@@ -0,0 +1,18 @@
|
||||
extends State
|
||||
|
||||
var starting_speed: float
|
||||
|
||||
func enter() -> void:
|
||||
super.enter()
|
||||
run_animation()
|
||||
agent.navigate_to_random_point()
|
||||
starting_speed = agent.speed
|
||||
agent.speed = agent.speed * 1.5
|
||||
|
||||
func physics_update(_delta) -> void:
|
||||
if agent.nav_agent.is_navigation_finished():
|
||||
transitioned.emit(self, get_next_state())
|
||||
|
||||
func exit() -> void:
|
||||
agent.speed = starting_speed
|
||||
super.exit()
|
||||
1
core/ai/framework/run_state.gd.uid
Normal file
1
core/ai/framework/run_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b5y4u0itec8g1
|
||||
@@ -4,7 +4,9 @@ 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 blend_time: float = 0.2
|
||||
@export var exit_on_action_finished: bool
|
||||
@export var exit_on_animation_finished: bool
|
||||
@export var min_wait_time: float = 3.0
|
||||
@@ -47,7 +49,7 @@ func physics_update(_delta: float) -> void:
|
||||
|
||||
func run_animation() -> void:
|
||||
if agent.anim_player and agent.anim_player.has_animation(animation_name):
|
||||
agent.anim_player.play(animation_name)
|
||||
agent.anim_player.play(animation_name, blend_time)
|
||||
|
||||
func _on_animation_finished(anim_name: StringName) -> void:
|
||||
if animation_name == anim_name:
|
||||
@@ -57,7 +59,12 @@ func _on_animation_finished(anim_name: StringName) -> void:
|
||||
var wait_time := randf_range(min_wait_time, max_wait_time)
|
||||
runtime_timer.start(wait_time)
|
||||
else:
|
||||
transitioned.emit(self, next_state_id)
|
||||
transitioned.emit(self, get_next_state())
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
transitioned.emit(self, next_state_id)
|
||||
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
|
||||
|
||||
37
core/ai/framework/wait_train_state.gd
Normal file
37
core/ai/framework/wait_train_state.gd
Normal file
@@ -0,0 +1,37 @@
|
||||
extends State
|
||||
|
||||
class_name WaitTrainState
|
||||
|
||||
@export var fly_distance_threshold: float = 30.0
|
||||
|
||||
var _train_node: Node3D = null
|
||||
|
||||
func enter() -> void:
|
||||
super.enter()
|
||||
run_animation()
|
||||
_train_node = _find_train_node()
|
||||
|
||||
func physics_update(_delta: float) -> void:
|
||||
if not _train_node:
|
||||
_train_node = _find_train_node()
|
||||
|
||||
if _train_node:
|
||||
var dist = agent.global_position.distance_to(_train_node.global_position)
|
||||
if dist <= fly_distance_threshold:
|
||||
transitioned.emit(self, get_next_state())
|
||||
|
||||
func _find_train_node() -> Node3D:
|
||||
var weather_nodes = get_tree().get_nodes_in_group("weather_node")
|
||||
for node in weather_nodes:
|
||||
if "Treno" in node.name or "Train" in node.name:
|
||||
return node as Node3D
|
||||
|
||||
var train = get_tree().root.find_child("*Treno*", true, false)
|
||||
if train and train is Node3D:
|
||||
return train as Node3D
|
||||
|
||||
train = get_tree().root.find_child("*Train*", true, false)
|
||||
if train and train is Node3D:
|
||||
return train as Node3D
|
||||
|
||||
return null
|
||||
1
core/ai/framework/wait_train_state.gd.uid
Normal file
1
core/ai/framework/wait_train_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://da5vhmxbxkdbc
|
||||
Reference in New Issue
Block a user