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 8621043..77d3f34 100644 Binary files a/demo/demo/assets/ui.theme and b/demo/demo/assets/ui.theme differ 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)