From 7949330c90f1d0a18e9a348984c4d9d95cdd8e4c Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Sun, 4 Feb 2024 16:00:43 +0100 Subject: [PATCH] Demo: Refactoring, docstrings and tweaks --- demo/demo/agents/02_agent_charger.tscn | 6 ++-- demo/demo/agents/06_agent_melee_combo.tscn | 13 +++++--- demo/demo/agents/scripts/agent_base.gd | 14 +++++--- demo/demo/agents/scripts/health.gd | 6 +++- demo/demo/agents/scripts/hitbox.gd | 6 ++++ demo/demo/agents/scripts/hurtbox.gd | 1 - demo/demo/ai/tasks/arrive_pos.gd | 15 +++++++-- demo/demo/ai/tasks/back_away.gd | 5 +++ demo/demo/ai/tasks/face_target.gd | 4 ++- demo/demo/ai/tasks/get_first_in_group.gd | 11 +++++-- demo/demo/ai/tasks/in_range.gd | 30 +++++++++++------- .../{leap_forward.gd => move_forward.gd} | 15 ++++++--- demo/demo/ai/tasks/pursue.gd | 17 +++++++--- demo/demo/ai/tasks/select_flanking_pos.gd | 10 +++--- .../demo/ai/tasks/select_random_nearby_pos.gd | 10 ++++-- demo/demo/ai/trees/02_agent_charger.tres | 9 +++--- demo/demo/ai/trees/06_agent_melee_combo.tres | 20 +++++++----- demo/demo/assets/ui.theme | Bin 2249124 -> 2249128 bytes demo/demo/props/dummy.gd | 2 ++ demo/demo/scenes/agent_showcase.gd | 2 +- 20 files changed, 133 insertions(+), 63 deletions(-) rename demo/demo/ai/tasks/{leap_forward.gd => move_forward.gd} (66%) diff --git a/demo/demo/agents/02_agent_charger.tscn b/demo/demo/agents/02_agent_charger.tscn index f50531c..c51dc00 100644 --- a/demo/demo/agents/02_agent_charger.tscn +++ b/demo/demo/agents/02_agent_charger.tscn @@ -4,7 +4,7 @@ [ext_resource type="Texture2D" uid="uid://ce16nc0wy2s8" path="res://demo/assets/agent_charger.png" id="2_y7pic"] [ext_resource type="BehaviorTree" uid="uid://ylife72ym5et" path="res://demo/ai/trees/02_agent_charger.tres" id="3_nacc3"] -[sub_resource type="BlackboardPlan" id="BlackboardPlan_b4r3u"] +[sub_resource type="BlackboardPlan" id="BlackboardPlan_pmyhf"] var/speed/name = "speed" var/speed/type = 3 var/speed/value = 400.0 @@ -12,7 +12,7 @@ var/speed/hint = 1 var/speed/hint_string = "10,1000,10" var/charge_speed/name = "charge_speed" var/charge_speed/type = 3 -var/charge_speed/value = 800.0 +var/charge_speed/value = 1000.0 var/charge_speed/hint = 1 var/charge_speed/hint_string = "10,1000,10" @@ -38,4 +38,4 @@ texture = ExtResource("2_y7pic") [node name="BTPlayer" type="BTPlayer" parent="." index="4"] behavior_tree = ExtResource("3_nacc3") -blackboard_plan = SubResource("BlackboardPlan_b4r3u") +blackboard_plan = SubResource("BlackboardPlan_pmyhf") diff --git a/demo/demo/agents/06_agent_melee_combo.tscn b/demo/demo/agents/06_agent_melee_combo.tscn index d630fb8..b382b78 100644 --- a/demo/demo/agents/06_agent_melee_combo.tscn +++ b/demo/demo/agents/06_agent_melee_combo.tscn @@ -4,12 +4,17 @@ [ext_resource type="Texture2D" uid="uid://bo0ibp7tvjbba" path="res://demo/assets/agent_combo.png" id="2_4rqld"] [ext_resource type="BehaviorTree" uid="uid://cpncl1db8j12f" path="res://demo/ai/trees/06_agent_melee_combo.tres" id="3_l805q"] -[sub_resource type="BlackboardPlan" id="BlackboardPlan_78rmu"] +[sub_resource type="BlackboardPlan" id="BlackboardPlan_67ric"] var/speed/name = "speed" var/speed/type = 3 var/speed/value = 400.0 var/speed/hint = 1 var/speed/hint_string = "10,1000,10" +var/charge_speed/name = "charge_speed" +var/charge_speed/type = 3 +var/charge_speed/value = 1000.0 +var/charge_speed/hint = 0 +var/charge_speed/hint_string = "" [node name="AgentMeleeCombo" instance=ExtResource("1_dny3b")] @@ -31,11 +36,9 @@ texture = ExtResource("2_4rqld") [node name="HandR" parent="Root/Rig/Body" index="2"] texture = ExtResource("2_4rqld") -[node name="WeaponNinjaStar" parent="Root" index="2"] -position = Vector2(-55, -76) -rotation = 0.0 +[node name="WeaponNinjaStar" parent="Root" index="1"] scale = Vector2(0.999983, 0.999976) [node name="BTPlayer" type="BTPlayer" parent="." index="4"] behavior_tree = ExtResource("3_l805q") -blackboard_plan = SubResource("BlackboardPlan_78rmu") +blackboard_plan = SubResource("BlackboardPlan_67ric") diff --git a/demo/demo/agents/scripts/agent_base.gd b/demo/demo/agents/scripts/agent_base.gd index 23653c2..a1084cf 100644 --- a/demo/demo/agents/scripts/agent_base.gd +++ b/demo/demo/agents/scripts/agent_base.gd @@ -10,9 +10,12 @@ #* extends CharacterBody2D -## Base agent script. +## Base agent script that is shared by all agents. +# Resource file to use in summon_minion() method. const MINION_RESOURCE := "res://demo/agents/03_agent_imp.tscn" + +# Projectile resource. const NinjaStar := preload("res://demo/agents/ninja_star/ninja_star.tscn") const Fireball := preload("res://demo/agents/fireball/fireball.tscn") @@ -22,21 +25,21 @@ const Fireball := preload("res://demo/agents/fireball/fireball.tscn") @onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D @onready var summoning_effect: GPUParticles2D = $FX/Summoned - var _frames_since_facing_update: int = 0 var _is_dead: bool = false + func _ready() -> void: health.damaged.connect(_damaged) health.death.connect(die) - +## Update agent's facing in the velocity direction. func update_facing() -> void: _frames_since_facing_update += 1 if _frames_since_facing_update > 3: face_dir(velocity.x) - +## Face specified direction. func face_dir(dir: float) -> void: if dir > 0.0 and root.scale.x < 0.0: root.scale.x = 1.0; @@ -72,6 +75,7 @@ func summon_minion(p_position: Vector2) -> void: minion.play_summoning_effect() +## Method is used when this agent is summoned from the dungeons of the castle AaaAaaAAAAAaaAAaaaaaa func play_summoning_effect() -> void: summoning_effect.emitting = true @@ -86,6 +90,7 @@ func is_good_position(p_position: Vector2) -> bool: return collision.is_empty() +## When agent is damaged... func _damaged(_amount: float, knockback: Vector2) -> void: apply_knockback(knockback) animation_player.play(&"hurt") @@ -102,6 +107,7 @@ func _damaged(_amount: float, knockback: Vector2) -> void: hsm.set_active(true) +## Push agent in the knockback direction for the specified number of physics frames. func apply_knockback(knockback: Vector2, frames: int = 10) -> void: if knockback.is_zero_approx(): return diff --git a/demo/demo/agents/scripts/health.gd b/demo/demo/agents/scripts/health.gd index ca1b9c4..c4126e8 100644 --- a/demo/demo/agents/scripts/health.gd +++ b/demo/demo/agents/scripts/health.gd @@ -12,10 +12,13 @@ class_name Health extends Node ## Tracks health and emits signal when damaged or dead. - +## Emitted when health is reduced to 0. signal death + +## Emitted when health is damaged. signal damaged(amount: float, knockback: Vector2) +## Initial health value. @export var max_health: float = 10.0 var _current: float @@ -38,5 +41,6 @@ func take_damage(amount: float, knockback: Vector2) -> void: damaged.emit(amount, knockback) +## Returns current health. func get_current() -> float: return _current diff --git a/demo/demo/agents/scripts/hitbox.gd b/demo/demo/agents/scripts/hitbox.gd index d8a9864..9fe85e6 100644 --- a/demo/demo/agents/scripts/hitbox.gd +++ b/demo/demo/agents/scripts/hitbox.gd @@ -12,10 +12,16 @@ class_name Hitbox extends Area2D ## Area that deals damage. +## Damage value to apply. @export var damage: float = 1.0 + +## Push back the victim. @export var knockback_enabled: bool = false + +## Desired pushback speed. @export var knockback_strength: float = 500.0 + func _ready() -> void: area_entered.connect(_area_entered) diff --git a/demo/demo/agents/scripts/hurtbox.gd b/demo/demo/agents/scripts/hurtbox.gd index b45eee9..3a21e74 100644 --- a/demo/demo/agents/scripts/hurtbox.gd +++ b/demo/demo/agents/scripts/hurtbox.gd @@ -12,7 +12,6 @@ class_name Hurtbox extends Area2D ## Area that registers damage. - @export var health: Health var last_attack_vector: Vector2 diff --git a/demo/demo/ai/tasks/arrive_pos.gd b/demo/demo/ai/tasks/arrive_pos.gd index f9ce775..03f1c09 100644 --- a/demo/demo/ai/tasks/arrive_pos.gd +++ b/demo/demo/ai/tasks/arrive_pos.gd @@ -10,11 +10,17 @@ #* @tool extends BTAction -## Arrive to a position, with a bias to horizontal movement. - +## ArrivePos: Arrive to a position, with a bias to horizontal movement. +## Returns SUCCESS when close to the target position (see tolerance); +## otherwise returns RUNNING. +## Blackboard variable that stores the target position (Vector2) @export var target_position_var := "pos" + +## Variable that stores desired speed (float) @export var speed_var := "speed" + +## How close should the agent be to the target position to return SUCCESS. @export var tolerance := 50.0 @@ -30,10 +36,13 @@ func _tick(_delta: float) -> Status: var speed: float = blackboard.get_var(speed_var, 10.0) var dist: float = absf(agent.global_position.x - target_pos.x) + var dir: Vector2 = agent.global_position.direction_to(target_pos) + + # Prefer horizontal movement: var vertical_factor: float = remap(dist, 200.0, 500.0, 1.0, 0.0) vertical_factor = clampf(vertical_factor, 0.0, 1.0) - var dir: Vector2 = agent.global_position.direction_to(target_pos) dir.y *= vertical_factor + var desired_velocity: Vector2 = dir.normalized() * speed agent.velocity = lerp(agent.velocity, desired_velocity, 0.2) agent.move_and_slide() diff --git a/demo/demo/ai/tasks/back_away.gd b/demo/demo/ai/tasks/back_away.gd index 8128cd6..374dc18 100644 --- a/demo/demo/ai/tasks/back_away.gd +++ b/demo/demo/ai/tasks/back_away.gd @@ -13,14 +13,19 @@ extends BTAction ## BackAway ## Returns RUNNING always. +## Blackboard variable that stores desired speed. @export var speed_var: String = "speed" + +## How much can we deviate from the "away" direction (in radians). @export var max_angle_deviation: float = 0.7 var _dir: Vector2 var _desired_velocity: Vector2 + # Called each time this task is entered. func _enter() -> void: + # Determine "away" direction and desired velocity _dir = Vector2.LEFT * agent.get_facing() var speed: float = blackboard.get_var(speed_var, 200.0) var rand_angle = randf_range(-max_angle_deviation, max_angle_deviation) diff --git a/demo/demo/ai/tasks/face_target.gd b/demo/demo/ai/tasks/face_target.gd index 04fddfe..a1f69a2 100644 --- a/demo/demo/ai/tasks/face_target.gd +++ b/demo/demo/ai/tasks/face_target.gd @@ -10,8 +10,10 @@ #* @tool extends BTAction -## FaceTarget +## FaceTarget and return SUCCESS. +## Returns FAILURE if target is not a valid Node2D instance. +## Blackboard variable that stores our target (expecting Node2D). @export var target_var: String = "target" # Display a customized name (requires @tool). diff --git a/demo/demo/ai/tasks/get_first_in_group.gd b/demo/demo/ai/tasks/get_first_in_group.gd index bbd3755..d4e17bc 100644 --- a/demo/demo/ai/tasks/get_first_in_group.gd +++ b/demo/demo/ai/tasks/get_first_in_group.gd @@ -10,10 +10,13 @@ #* @tool extends BTAction - ## Get first node in group and save it to the blackboard. +## Returns FAILURE if group contains 0 nodes. +## Name of the SceneTree group. @export var group: StringName + +## Blackboard variable in which the task will store the acquired node. @export var output_var: String = "target" @@ -24,6 +27,8 @@ func _generate_name() -> String: ] func _tick(_delta: float) -> Status: - var node = agent.get_tree().get_first_node_in_group(group) - blackboard.set_var(output_var, node) + var nodes: Array[Node] = agent.get_tree().get_nodes_in_group(group) + if nodes.size() == 0: + return FAILURE + blackboard.set_var(output_var, nodes[0]) return SUCCESS diff --git a/demo/demo/ai/tasks/in_range.gd b/demo/demo/ai/tasks/in_range.gd index d01a1c5..0a9f106 100644 --- a/demo/demo/ai/tasks/in_range.gd +++ b/demo/demo/ai/tasks/in_range.gd @@ -16,8 +16,13 @@ extends BTCondition ## Returns SUCCESS if the agent is within the defined range; ## otherwise, returns FAILURE. +## Minimum distance to target. @export var distance_min: float + +## Maximum distance to target. @export var distance_max: float + +## Blackboard variable that holds the target (expecting Node2D). @export var target_var := "target" var _min_distance_squared: float @@ -26,24 +31,25 @@ var _max_distance_squared: float # Called to generate a display name for the task. func _generate_name() -> String: - return "InRange (%d, %d) of %s" % [distance_min, distance_max, - LimboUtility.decorate_var(target_var)] + return "InRange (%d, %d) of %s" % [distance_min, distance_max, + LimboUtility.decorate_var(target_var)] # Called to initialize the task. func _setup() -> void: - _min_distance_squared = distance_min * distance_min - _max_distance_squared = distance_max * distance_max + ## Small performace optimization + _min_distance_squared = distance_min * distance_min + _max_distance_squared = distance_max * distance_max # Called when the task is executed. func _tick(_delta: float) -> Status: - var target: Node2D = blackboard.get_var(target_var, null) - if not is_instance_valid(target): - return FAILURE + var target: Node2D = blackboard.get_var(target_var, null) + if not is_instance_valid(target): + return FAILURE - var dist_sq: float = agent.global_position.distance_squared_to(target.global_position) - if dist_sq >= _min_distance_squared and dist_sq <= _max_distance_squared: - return SUCCESS - else: - return FAILURE + var dist_sq: float = agent.global_position.distance_squared_to(target.global_position) + if dist_sq >= _min_distance_squared and dist_sq <= _max_distance_squared: + return SUCCESS + else: + return FAILURE diff --git a/demo/demo/ai/tasks/leap_forward.gd b/demo/demo/ai/tasks/move_forward.gd similarity index 66% rename from demo/demo/ai/tasks/leap_forward.gd rename to demo/demo/ai/tasks/move_forward.gd index 6ac32fe..9326755 100644 --- a/demo/demo/ai/tasks/leap_forward.gd +++ b/demo/demo/ai/tasks/move_forward.gd @@ -1,5 +1,5 @@ #* -#* leap_forward.gd +#* move_forward.gd #* ============================================================================= #* Copyright 2021-2024 Serhii Snitsaruk #* @@ -10,22 +10,27 @@ #* @tool extends BTAction -## LeapForward: Applies force each tick until duration is exceeded. +## MoveForward: Applies velocity each tick until duration is exceeded. ## Returns SUCCESS if elapsed time exceeded duration. ## Returns RUNNING if elapsed time didn't exceed duration. +## Blackboard variable that stores desired speed. +@export var speed_var: String = "speed" -@export var force: float = 1000.0 +## How long to perform this task (in seconds). @export var duration: float = 0.1 # Display a customized name (requires @tool). func _generate_name() -> String: - return "LeapForward force: " + str(force) + return "MoveForward speed: %s duration: %ss" % [ + LimboUtility.decorate_var(speed_var), + duration] # Called each time this task is ticked (aka executed). func _tick(_delta: float) -> Status: var facing: float = agent.get_facing() - var desired_velocity: Vector2 = Vector2.RIGHT * facing * force + var speed: float = blackboard.get_var(speed_var, 100.0) + var desired_velocity: Vector2 = Vector2.RIGHT * facing * speed agent.velocity = lerp(agent.velocity, desired_velocity, 0.2) agent.move_and_slide() agent.update_facing() diff --git a/demo/demo/ai/tasks/pursue.gd b/demo/demo/ai/tasks/pursue.gd index a08b6d2..430a1ac 100644 --- a/demo/demo/ai/tasks/pursue.gd +++ b/demo/demo/ai/tasks/pursue.gd @@ -16,24 +16,32 @@ extends BTAction ## Returns SUCCESS, when at the desired position from target (flanking it). ## Returns FAILURE, if target is not a valid Node2D instance. - +## How close should the agent be to the desired position to return SUCCESS. const TOLERANCE := 30.0 +## Blackboard variable that stores our target (expecting Node2D). @export var target_var: String = "target" + +## Blackboard variable that stores desired speed. @export var speed_var: String = "speed" + +## Desired distance from target. @export var approach_distance: float = 100.0 -#var _side: float var _waypoint: Vector2 + # Display a customized name (requires @tool). func _generate_name() -> String: return "Pursue %s" % [LimboUtility.decorate_var(target_var)] +# Called each time this task is entered. func _enter() -> void: var target: Node2D = blackboard.get_var(target_var, null) if is_instance_valid(target): + # Movement is performed in smaller steps. + # For each step, we select a new waypoint. _select_new_waypoint(_get_desired_position(target)) @@ -47,9 +55,10 @@ func _tick(_delta: float) -> Status: if agent.global_position.distance_to(desired_pos) < TOLERANCE: return SUCCESS - var speed: float = blackboard.get_var(speed_var, 200.0) if agent.global_position.distance_to(_waypoint) < TOLERANCE: _select_new_waypoint(desired_pos) + + var speed: float = blackboard.get_var(speed_var, 200.0) var desired_velocity: Vector2 = agent.global_position.direction_to(_waypoint) * speed agent.velocity = lerp(agent.velocity, desired_velocity, 0.2) agent.move_and_slide() @@ -57,7 +66,7 @@ func _tick(_delta: float) -> Status: return RUNNING -## Get closest flanking position to target. +## Get the closest flanking position to target. func _get_desired_position(target: Node2D) -> Vector2: var side: float = signf(agent.global_position.x - target.global_position.x) var desired_pos: Vector2 = target.global_position diff --git a/demo/demo/ai/tasks/select_flanking_pos.gd b/demo/demo/ai/tasks/select_flanking_pos.gd index 4c6729c..c465515 100644 --- a/demo/demo/ai/tasks/select_flanking_pos.gd +++ b/demo/demo/ai/tasks/select_flanking_pos.gd @@ -23,9 +23,7 @@ enum AgentSide { ## Blackboard variable that holds current target (should be a Node2D instance). @export var target_var: String = "target" -## Should closest side be selected? -@export var closest_side: bool = false - +## Which agent's side should we flank? @export var flank_side: AgentSide = AgentSide.CLOSEST ## Minimum range relative to the target. @@ -37,6 +35,7 @@ enum AgentSide { ## Blackboard variable that will be used to store selected position. @export var position_var: String = "pos" + # Display a customized name (requires @tool). func _generate_name() -> String: return "SelectFlankingPos target: %s range: [%s, %s] side: %s ➜%s" % [ @@ -46,17 +45,18 @@ func _generate_name() -> String: AgentSide.keys()[flank_side], LimboUtility.decorate_var(position_var)] + # Called each time this task is ticked (aka executed). func _tick(_delta: float) -> Status: var target := blackboard.get_var(target_var) as Node2D if not is_instance_valid(target): return FAILURE - var dir: float + var dir: float # 1.0 is right, -1.0 is left (relative to target) match flank_side: AgentSide.FARTHEST: dir = signf(target.global_position.x - agent.global_position.x) - AgentSide.CLOSEST: + AgentSide.CLOSEST : dir = -signf(target.global_position.x - agent.global_position.x) AgentSide.BACK: dir = -target.get_facing() diff --git a/demo/demo/ai/tasks/select_random_nearby_pos.gd b/demo/demo/ai/tasks/select_random_nearby_pos.gd index 2f93d6e..8dd792c 100644 --- a/demo/demo/ai/tasks/select_random_nearby_pos.gd +++ b/demo/demo/ai/tasks/select_random_nearby_pos.gd @@ -3,23 +3,29 @@ extends BTAction ## SelectRandomNearbyPos: Select a position nearby within specified range. ## Returns SUCCESS. -## Maximum distance to the desired position. +## Minimum distance to the desired position. @export var range_min: float = 300.0 + +## Maximum distance to the desired position. @export var range_max: float = 500.0 + +## Blackboard variable that will be used to store the desired position. @export var position_var: String = "pos" + # Display a customized name (requires @tool). func _generate_name() -> String: return "SelectRandomNearbyPos range: [%s, %s] ➜%s" % [ range_min, range_max, LimboUtility.decorate_var(position_var)] + # Called each time this task is ticked (aka executed). func _tick(_delta: float) -> Status: var pos: Vector2 var is_good_position: bool = false while not is_good_position: - # Randomize until we find a good position (in other words, not outside the arena) + # Randomize until we find a good position (good position == not outside the arena). var angle: float = randf() * TAU var rand_distance: float = randf_range(range_min, range_max) pos = agent.global_position + Vector2(sin(angle), cos(angle)) * rand_distance diff --git a/demo/demo/ai/trees/02_agent_charger.tres b/demo/demo/ai/trees/02_agent_charger.tres index 52c738a..cc382e9 100644 --- a/demo/demo/ai/trees/02_agent_charger.tres +++ b/demo/demo/ai/trees/02_agent_charger.tres @@ -4,7 +4,7 @@ [ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_t3udh"] [ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="3_u2ra5"] [ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="4_xwjl7"] -[ext_resource type="Script" path="res://demo/ai/tasks/leap_forward.gd" id="5_f6dg8"] +[ext_resource type="Script" path="res://demo/ai/tasks/move_forward.gd" id="5_ucvak"] [sub_resource type="BlackboardPlan" id="BlackboardPlan_qd806"] var/speed/name = "speed" @@ -14,7 +14,7 @@ var/speed/hint = 1 var/speed/hint_string = "10,1000,10" var/charge_speed/name = "charge_speed" var/charge_speed/type = 3 -var/charge_speed/value = 800.0 +var/charge_speed/value = 1000.0 var/charge_speed/hint = 1 var/charge_speed/hint_string = "10,1000,10" @@ -43,7 +43,6 @@ output_var = "target" [sub_resource type="BTAction" id="BTAction_pmvd0"] script = ExtResource("2_t3udh") target_var = "target" -closest_side = false flank_side = 0 range_min = 500 range_max = 600 @@ -98,8 +97,8 @@ animation_name = &"charge" blend = 0.05 [sub_resource type="BTAction" id="BTAction_o18uk"] -script = ExtResource("5_f6dg8") -force = 1000.0 +script = ExtResource("5_ucvak") +speed_var = "charge_speed" duration = 2.0 [sub_resource type="BTSequence" id="BTSequence_8lur1"] diff --git a/demo/demo/ai/trees/06_agent_melee_combo.tres b/demo/demo/ai/trees/06_agent_melee_combo.tres index 7748cd2..1eb62d2 100644 --- a/demo/demo/ai/trees/06_agent_melee_combo.tres +++ b/demo/demo/ai/trees/06_agent_melee_combo.tres @@ -4,7 +4,7 @@ [ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_5nwkp"] [ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="3_3tom2"] [ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="4_hi228"] -[ext_resource type="Script" path="res://demo/ai/tasks/leap_forward.gd" id="5_fpbac"] +[ext_resource type="Script" path="res://demo/ai/tasks/move_forward.gd" id="5_au5yc"] [sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"] var/speed/name = "speed" @@ -12,6 +12,11 @@ var/speed/type = 3 var/speed/value = 400.0 var/speed/hint = 1 var/speed/hint_string = "10,1000,10" +var/charge_speed/name = "charge_speed" +var/charge_speed/type = 3 +var/charge_speed/value = 1000.0 +var/charge_speed/hint = 0 +var/charge_speed/hint_string = "" [sub_resource type="BBNode" id="BBNode_nrd4b"] saved_value = NodePath("AnimationPlayer") @@ -38,7 +43,6 @@ children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud [sub_resource type="BTAction" id="BTAction_85keo"] script = ExtResource("2_5nwkp") target_var = "target" -closest_side = true flank_side = 0 range_min = 300 range_max = 400 @@ -83,8 +87,8 @@ animation_player = SubResource("BBNode_s8evu") animation_name = &"attack_1" [sub_resource type="BTAction" id="BTAction_u22bc"] -script = ExtResource("5_fpbac") -force = 1000.0 +script = ExtResource("5_au5yc") +speed_var = "charge_speed" duration = 0.1 [sub_resource type="BTParallel" id="BTParallel_ec2e3"] @@ -104,8 +108,8 @@ animation_player = SubResource("BBNode_3oljv") animation_name = &"attack_2" [sub_resource type="BTAction" id="BTAction_yuxl3"] -script = ExtResource("5_fpbac") -force = 1000.0 +script = ExtResource("5_au5yc") +speed_var = "charge_speed" duration = 0.1 [sub_resource type="BTParallel" id="BTParallel_thojy"] @@ -125,8 +129,8 @@ animation_player = SubResource("BBNode_ot40l") animation_name = &"attack_3" [sub_resource type="BTAction" id="BTAction_rwp18"] -script = ExtResource("5_fpbac") -force = 1000.0 +script = ExtResource("5_au5yc") +speed_var = "charge_speed" duration = 0.1 [sub_resource type="BTParallel" id="BTParallel_qmdfb"] diff --git a/demo/demo/assets/ui.theme b/demo/demo/assets/ui.theme index 862104347d2519953a02066df6c5388cae9f7278..77d3f342c848cdbf4039f7da787efc12955c43fb 100644 GIT binary patch delta 1384 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 diff --git a/demo/demo/props/dummy.gd b/demo/demo/props/dummy.gd index 2047fd5..06fc9f3 100644 --- a/demo/demo/props/dummy.gd +++ b/demo/demo/props/dummy.gd @@ -4,10 +4,12 @@ extends CharacterBody2D @onready var hurtbox: Hurtbox = $Hurtbox @onready var root: Node2D = $Root + func _on_health_damaged(_amount: float, _knockback: Vector2) -> void: root.scale.x = -signf(hurtbox.last_attack_vector.x) animation_player.clear_queue() animation_player.play(&"hurt", 0.1) + func get_facing() -> float: return signf(root.scale.x) diff --git a/demo/demo/scenes/agent_showcase.gd b/demo/demo/scenes/agent_showcase.gd index a193582..9f0a2e3 100644 --- a/demo/demo/scenes/agent_showcase.gd +++ b/demo/demo/scenes/agent_showcase.gd @@ -77,4 +77,4 @@ func _on_agent_selection_id_pressed(id: int) -> void: _load_agent("res://demo/agents/".path_join(agent_files[id])) agent_selection.text = bt_player.behavior_tree.resource_path.get_file() previous.disabled = id == 0 - next.disabled = id == 8 + next.disabled = id == (agent_files.size()-1)