Adds enemies
5
demo/LICENSE_ASSETS.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
LimboAI Demo project graphical assets (PNG & SVG files in the "assets/" folder)
|
||||
Copyright (c) 2024 Aleksandra Snitsaruk
|
||||
|
||||
This work is licensed under the Creative Commons Attribution 4.0 International
|
||||
license (CC BY 4.0 International): https://creativecommons.org/licenses/by/4.0/
|
||||
34
demo/agents/01_agent_melee_simple.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://1dnm7tuik8xo"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_l180o"]
|
||||
[ext_resource type="Texture2D" uid="uid://cw8s50856x8ct" path="res://demo/assets/agent_melee_simple.png" id="2_bvbes"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://bpdm5jnegi38" path="res://demo/ai/trees/01_agent_melee_simple.tres" id="3_tb7cx"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_s08ac"]
|
||||
|
||||
[node name="AgentMeleeSimple" instance=ExtResource("1_l180o")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_bvbes")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_bvbes")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_bvbes")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_bvbes")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_bvbes")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_bvbes")
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 3.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_tb7cx")
|
||||
blackboard_plan = SubResource("BlackboardPlan_s08ac")
|
||||
37
demo/agents/02_agent_charger.tscn
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://g1pnvanyxcpa"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_n83hi"]
|
||||
[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_pmyhf"]
|
||||
|
||||
[node name="AgentCharger" instance=ExtResource("1_n83hi")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="Hitbox" parent="Root" index="1"]
|
||||
damage = 2.0
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 8.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="4"]
|
||||
behavior_tree = ExtResource("3_nacc3")
|
||||
blackboard_plan = SubResource("BlackboardPlan_pmyhf")
|
||||
34
demo/agents/03_agent_imp.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://730bthc0ywhd"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_13xup"]
|
||||
[ext_resource type="Texture2D" uid="uid://h70okn6hmxum" path="res://demo/assets/agent_imp.png" id="2_xd5s8"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://c2bxoo68ywb27" path="res://demo/ai/trees/03_agent_imp.tres" id="3_furh3"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_aog23"]
|
||||
|
||||
[node name="AgentImp" instance=ExtResource("1_13xup")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_xd5s8")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_xd5s8")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_xd5s8")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_xd5s8")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_xd5s8")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_xd5s8")
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 4.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_furh3")
|
||||
blackboard_plan = SubResource("BlackboardPlan_aog23")
|
||||
34
demo/agents/04_agent_skirmisher.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://co6yeafaljbq0"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_2ir76"]
|
||||
[ext_resource type="Texture2D" uid="uid://l042ovqqsy3l" path="res://demo/assets/agent_skirmisher.png" id="2_w8tqw"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://qqmjvbeibatn" path="res://demo/ai/trees/04_agent_skirmisher.tres" id="3_bhfkv"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_vjbry"]
|
||||
|
||||
[node name="AgentSkirmisher" instance=ExtResource("1_2ir76")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_w8tqw")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_w8tqw")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_w8tqw")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_w8tqw")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_w8tqw")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_w8tqw")
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 7.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="4"]
|
||||
behavior_tree = ExtResource("3_bhfkv")
|
||||
blackboard_plan = SubResource("BlackboardPlan_vjbry")
|
||||
34
demo/agents/05_agent_ranged.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://ci3x5esepbu5v"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_oa4xm"]
|
||||
[ext_resource type="Texture2D" uid="uid://cjts4ennjtepg" path="res://demo/assets/agent_ranged.png" id="2_37lvn"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://cqluon1y1hnn5" path="res://demo/ai/trees/05_agent_ranged.tres" id="3_f7r5w"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_2kwy7"]
|
||||
|
||||
[node name="AgentRanged" instance=ExtResource("1_oa4xm")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_37lvn")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_37lvn")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_37lvn")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_37lvn")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_37lvn")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_37lvn")
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 6.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="4"]
|
||||
behavior_tree = ExtResource("3_f7r5w")
|
||||
blackboard_plan = SubResource("BlackboardPlan_2kwy7")
|
||||
34
demo/agents/06_agent_melee_combo.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://blxmw2w1h2s0s"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_dny3b"]
|
||||
[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_67ric"]
|
||||
|
||||
[node name="AgentMeleeCombo" instance=ExtResource("1_dny3b")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_4rqld")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_4rqld")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_4rqld")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_4rqld")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_4rqld")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_4rqld")
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 6.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="4"]
|
||||
behavior_tree = ExtResource("3_l805q")
|
||||
blackboard_plan = SubResource("BlackboardPlan_67ric")
|
||||
34
demo/agents/07_agent_melee_nuanced.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://2e4ohaqjaawb"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_afx5l"]
|
||||
[ext_resource type="Texture2D" uid="uid://usu3j55d6dgc" path="res://demo/assets/agent_melee_nuanced.png" id="2_e51r0"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://c2u6sljqkim0n" path="res://demo/ai/trees/07_agent_melee_nuanced.tres" id="3_b8kcf"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_tnf02"]
|
||||
|
||||
[node name="AgentMeleeNuanced" instance=ExtResource("1_afx5l")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_e51r0")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_e51r0")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_e51r0")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_e51r0")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_e51r0")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_e51r0")
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 6.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="4"]
|
||||
behavior_tree = ExtResource("3_b8kcf")
|
||||
blackboard_plan = SubResource("BlackboardPlan_tnf02")
|
||||
34
demo/agents/08_agent_demon.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://dbmcufef0cc4b"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_115kp"]
|
||||
[ext_resource type="Texture2D" uid="uid://d1tx7u8ho0r4v" path="res://demo/assets/agent_demon.png" id="2_cb5f2"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://cpcnbi81jqge4" path="res://demo/ai/trees/08_agent_demon.tres" id="3_ebd57"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_5sr4g"]
|
||||
|
||||
[node name="AgentDemon" instance=ExtResource("1_115kp")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 8.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_ebd57")
|
||||
blackboard_plan = SubResource("BlackboardPlan_5sr4g")
|
||||
34
demo/agents/09_agent_summoner.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://bycvi2fb0f7ue"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_neifu"]
|
||||
[ext_resource type="Texture2D" uid="uid://ombnpn2edldt" path="res://demo/assets/agent_summoner.png" id="2_fcti4"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://cpxk7jnqpwwlc" path="res://demo/ai/trees/09_agent_summoner.tres" id="3_bunpq"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_bqv3d"]
|
||||
|
||||
[node name="AgentSummoner" instance=ExtResource("1_neifu")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_fcti4")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_fcti4")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_fcti4")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_fcti4")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_fcti4")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_fcti4")
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 8.0
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_bunpq")
|
||||
blackboard_plan = SubResource("BlackboardPlan_bqv3d")
|
||||
4528
demo/agents/agent_base.tscn
Normal file
56
demo/agents/fireball/fireball.gd
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#*
|
||||
#* fireball.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends Node2D
|
||||
## Fireball
|
||||
|
||||
const SPEED := 800.0
|
||||
const DEAD_SPEED := 400.0
|
||||
|
||||
@export var dir: float = 1.0
|
||||
|
||||
var _is_dead: bool = false
|
||||
|
||||
@onready var fireball_sprite: Sprite2D = $Root/Fireball
|
||||
@onready var death: GPUParticles2D = $FX/Death
|
||||
@onready var collision_shape_2d: CollisionShape2D = $Hitbox/CollisionShape2D
|
||||
@onready var root: Node2D = $Root
|
||||
@onready var trail: GPUParticles2D = $FX/Trail
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var tween := create_tween().set_loops()
|
||||
tween.tween_property(fireball_sprite, ^"rotation", PI * signf(dir), 1.0).as_relative()
|
||||
|
||||
var tween2 := create_tween().set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
|
||||
tween2.tween_property(fireball_sprite, "position:y", -10.0, 0.5).as_relative().set_ease(Tween.EASE_OUT)
|
||||
tween2.tween_property(fireball_sprite, "position:y", 0.0, 1.0)
|
||||
tween2.tween_callback(_die)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var speed: float = SPEED if not _is_dead else DEAD_SPEED
|
||||
position += Vector2.RIGHT * speed * dir * delta
|
||||
|
||||
|
||||
func _die() -> void:
|
||||
if _is_dead:
|
||||
return
|
||||
_is_dead = true
|
||||
trail.emitting = false
|
||||
root.hide()
|
||||
collision_shape_2d.set_deferred(&"disabled", true)
|
||||
death.emitting = true
|
||||
await death.finished
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_hitbox_area_entered(_area: Area2D) -> void:
|
||||
_die()
|
||||
169
demo/agents/fireball/fireball.tscn
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
[gd_scene load_steps=18 format=3 uid="uid://wdauoepicegb"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/agents/fireball/fireball.gd" id="1_ituf4"]
|
||||
[ext_resource type="Texture2D" uid="uid://dwhhxj5557qrb" path="res://demo/assets/shadow.png" id="2_6n8mx"]
|
||||
[ext_resource type="Texture2D" uid="uid://235liwnxn1n5" path="res://demo/assets/fireball.png" id="3_1an0e"]
|
||||
[ext_resource type="Script" path="res://demo/agents/scripts/hitbox.gd" id="4_rjhgc"]
|
||||
[ext_resource type="Texture2D" uid="uid://bdusy0qqtw0th" path="res://demo/assets/smoke.png" id="5_dcbp6"]
|
||||
|
||||
[sub_resource type="Curve" id="Curve_mukra"]
|
||||
_data = [Vector2(0, 0), 0.0, 4.81319, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_56342"]
|
||||
curve = SubResource("Curve_mukra")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gbya7"]
|
||||
lifetime_randomness = 0.5
|
||||
particle_flag_disable_z = true
|
||||
direction = Vector3(0, -1, 0)
|
||||
spread = 90.0
|
||||
initial_velocity_min = 150.0
|
||||
initial_velocity_max = 250.0
|
||||
angular_velocity_min = -90.0
|
||||
angular_velocity_max = 90.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
radial_accel_min = -90.0
|
||||
radial_accel_max = 90.0
|
||||
damping_min = 200.0
|
||||
damping_max = 200.0
|
||||
scale_min = 0.8
|
||||
scale_max = 1.2
|
||||
scale_curve = SubResource("CurveTexture_56342")
|
||||
color = Color(0.552941, 0.552941, 0.552941, 1)
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_c08h3"]
|
||||
offsets = PackedFloat32Array(0, 0.549738, 1)
|
||||
colors = PackedColorArray(0.980453, 0.717632, 0.282353, 1, 0.960906, 0.211521, 0.0390784, 1, 0.201527, 0.201527, 0.201527, 1)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_fhxvw"]
|
||||
gradient = SubResource("Gradient_c08h3")
|
||||
|
||||
[sub_resource type="Curve" id="Curve_ugmtv"]
|
||||
_data = [Vector2(0, 0.010989), 0.0, 0.0, 0, 0, Vector2(0.151111, 1), 1.3559, 1.3559, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_1f5jp"]
|
||||
curve = SubResource("Curve_ugmtv")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gilhy"]
|
||||
lifetime_randomness = 0.5
|
||||
particle_flag_disable_z = true
|
||||
emission_shape = 3
|
||||
emission_box_extents = Vector3(40, 1, 1)
|
||||
direction = Vector3(0, -1, 0)
|
||||
spread = 90.0
|
||||
initial_velocity_min = 150.0
|
||||
initial_velocity_max = 250.0
|
||||
angular_velocity_min = -90.0
|
||||
angular_velocity_max = 90.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
radial_accel_min = -90.0
|
||||
radial_accel_max = 90.0
|
||||
damping_min = 200.0
|
||||
damping_max = 200.0
|
||||
scale_min = 0.8
|
||||
scale_max = 1.2
|
||||
scale_curve = SubResource("CurveTexture_1f5jp")
|
||||
color_ramp = SubResource("GradientTexture1D_fhxvw")
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_7uc1b"]
|
||||
radius = 25.13
|
||||
|
||||
[sub_resource type="Animation" id="Animation_wr7y0"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Root/Fireball:frame")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_ey8it"]
|
||||
resource_name = "default"
|
||||
length = 0.3
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Root/Fireball:frame")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
||||
"update": 1,
|
||||
"values": [0, 1, 2, 0]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_cphpk"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_wr7y0"),
|
||||
"default": SubResource("Animation_ey8it")
|
||||
}
|
||||
|
||||
[node name="Fireball" type="Node2D"]
|
||||
script = ExtResource("1_ituf4")
|
||||
|
||||
[node name="FX" type="Node2D" parent="."]
|
||||
position = Vector2(0, -92)
|
||||
|
||||
[node name="Trail" type="GPUParticles2D" parent="FX"]
|
||||
show_behind_parent = true
|
||||
amount = 6
|
||||
process_material = SubResource("ParticleProcessMaterial_gbya7")
|
||||
texture = ExtResource("5_dcbp6")
|
||||
lifetime = 0.4
|
||||
fixed_fps = 60
|
||||
|
||||
[node name="Death" type="GPUParticles2D" parent="FX"]
|
||||
emitting = false
|
||||
amount = 6
|
||||
process_material = SubResource("ParticleProcessMaterial_gilhy")
|
||||
texture = ExtResource("5_dcbp6")
|
||||
lifetime = 0.7
|
||||
one_shot = true
|
||||
explosiveness = 0.7
|
||||
fixed_fps = 60
|
||||
local_coords = true
|
||||
|
||||
[node name="Root" type="Node2D" parent="."]
|
||||
|
||||
[node name="Shadow" type="Sprite2D" parent="Root"]
|
||||
modulate = Color(1, 1, 1, 0.686275)
|
||||
position = Vector2(0, -1)
|
||||
scale = Vector2(0.382, 0.297)
|
||||
texture = ExtResource("2_6n8mx")
|
||||
|
||||
[node name="Fireball" type="Sprite2D" parent="Root"]
|
||||
position = Vector2(0, -92)
|
||||
texture = ExtResource("3_1an0e")
|
||||
hframes = 3
|
||||
|
||||
[node name="RemoteTransform2D" type="RemoteTransform2D" parent="Root/Fireball"]
|
||||
remote_path = NodePath("../../../FX")
|
||||
update_rotation = false
|
||||
update_scale = false
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="."]
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
script = ExtResource("4_rjhgc")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"]
|
||||
shape = SubResource("CircleShape2D_7uc1b")
|
||||
debug_color = Color(0.839216, 0.192157, 0.815686, 0.419608)
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_cphpk")
|
||||
}
|
||||
autoplay = "default"
|
||||
|
||||
[connection signal="area_entered" from="Hitbox" to="." method="_on_hitbox_area_entered"]
|
||||
53
demo/agents/ninja_star/ninja_star.gd
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#*
|
||||
#* ninja_star.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends Node2D
|
||||
|
||||
const SPEED := 800.0
|
||||
const DEAD_SPEED := 400.0
|
||||
|
||||
@export var dir: float = 1.0
|
||||
|
||||
var _is_dead: bool = false
|
||||
|
||||
@onready var ninja_star: Sprite2D = $Root/NinjaStar
|
||||
@onready var death: GPUParticles2D = $Death
|
||||
@onready var collision_shape_2d: CollisionShape2D = $Hitbox/CollisionShape2D
|
||||
@onready var root: Node2D = $Root
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var tween := create_tween().set_loops()
|
||||
tween.tween_property(ninja_star, ^"rotation", TAU * signf(dir), 1.0).as_relative()
|
||||
|
||||
var tween2 := create_tween().set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
|
||||
tween2.tween_property(ninja_star, "position:y", -10.0, 0.5).as_relative().set_ease(Tween.EASE_OUT)
|
||||
tween2.tween_property(ninja_star, "position:y", 0.0, 1.0)
|
||||
tween2.tween_callback(_die)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var speed: float = SPEED if not _is_dead else DEAD_SPEED
|
||||
position += Vector2.RIGHT * speed * dir * delta
|
||||
|
||||
|
||||
func _die() -> void:
|
||||
if _is_dead:
|
||||
return
|
||||
_is_dead = true
|
||||
root.hide()
|
||||
collision_shape_2d.set_deferred(&"disabled", true)
|
||||
death.emitting = true
|
||||
await death.finished
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_hitbox_area_entered(_area: Area2D) -> void:
|
||||
_die()
|
||||
80
demo/agents/ninja_star/ninja_star.tscn
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
[gd_scene load_steps=10 format=3 uid="uid://bj5n72nomeaci"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/agents/ninja_star/ninja_star.gd" id="1_pja57"]
|
||||
[ext_resource type="Texture2D" uid="uid://2uyxh7sy8qny" path="res://demo/assets/weapon_ninja_star.png" id="1_ptof7"]
|
||||
[ext_resource type="Texture2D" uid="uid://dwhhxj5557qrb" path="res://demo/assets/shadow.png" id="2_2rj5a"]
|
||||
[ext_resource type="Script" path="res://demo/agents/scripts/hitbox.gd" id="2_iem02"]
|
||||
[ext_resource type="Texture2D" uid="uid://bdusy0qqtw0th" path="res://demo/assets/smoke.png" id="5_t37aw"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_7uc1b"]
|
||||
radius = 28.0
|
||||
|
||||
[sub_resource type="Curve" id="Curve_ugmtv"]
|
||||
_data = [Vector2(0, 0.010989), 0.0, 0.0, 0, 0, Vector2(0.151111, 1), 1.3559, 1.3559, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_1f5jp"]
|
||||
curve = SubResource("Curve_ugmtv")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gilhy"]
|
||||
lifetime_randomness = 0.5
|
||||
particle_flag_disable_z = true
|
||||
emission_shape = 3
|
||||
emission_box_extents = Vector3(40, 1, 1)
|
||||
direction = Vector3(0, -1, 0)
|
||||
spread = 90.0
|
||||
initial_velocity_min = 150.0
|
||||
initial_velocity_max = 250.0
|
||||
angular_velocity_min = -90.0
|
||||
angular_velocity_max = 90.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
radial_accel_min = -90.0
|
||||
radial_accel_max = 90.0
|
||||
damping_min = 200.0
|
||||
damping_max = 200.0
|
||||
scale_min = 0.8
|
||||
scale_max = 1.2
|
||||
scale_curve = SubResource("CurveTexture_1f5jp")
|
||||
|
||||
[node name="NinjaStar" type="Node2D"]
|
||||
script = ExtResource("1_pja57")
|
||||
|
||||
[node name="Root" type="Node2D" parent="."]
|
||||
|
||||
[node name="Shadow" type="Sprite2D" parent="Root"]
|
||||
modulate = Color(1, 1, 1, 0.686275)
|
||||
position = Vector2(0, -1)
|
||||
scale = Vector2(0.382, 0.297)
|
||||
texture = ExtResource("2_2rj5a")
|
||||
|
||||
[node name="NinjaStar" type="Sprite2D" parent="Root"]
|
||||
position = Vector2(0, -93)
|
||||
texture = ExtResource("1_ptof7")
|
||||
|
||||
[node name="RemoteTransform2D" type="RemoteTransform2D" parent="Root/NinjaStar"]
|
||||
remote_path = NodePath("../../../Death")
|
||||
update_rotation = false
|
||||
update_scale = false
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="."]
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
script = ExtResource("2_iem02")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"]
|
||||
shape = SubResource("CircleShape2D_7uc1b")
|
||||
debug_color = Color(0.839216, 0.192157, 0.815686, 0.419608)
|
||||
|
||||
[node name="Death" type="GPUParticles2D" parent="."]
|
||||
position = Vector2(0, -93)
|
||||
emitting = false
|
||||
amount = 1
|
||||
process_material = SubResource("ParticleProcessMaterial_gilhy")
|
||||
texture = ExtResource("5_t37aw")
|
||||
lifetime = 0.7
|
||||
one_shot = true
|
||||
explosiveness = 0.7
|
||||
fixed_fps = 60
|
||||
local_coords = true
|
||||
|
||||
[connection signal="area_entered" from="Hitbox" to="." method="_on_hitbox_area_entered"]
|
||||
103
demo/agents/player/player.gd
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#*
|
||||
#* player.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends "res://demo/agents/scripts/agent_base.gd"
|
||||
|
||||
## Player.
|
||||
|
||||
@export var dodge_cooldown: float = 0.4
|
||||
|
||||
@onready var hsm: LimboHSM = $LimboHSM
|
||||
@onready var idle_state: LimboState = $LimboHSM/IdleState
|
||||
@onready var move_state: LimboState = $LimboHSM/MoveState
|
||||
@onready var attack_state: LimboState = $LimboHSM/AttackState
|
||||
@onready var dodge_state: LimboState = $LimboHSM/DodgeState
|
||||
|
||||
var can_dodge: bool = true
|
||||
var attack_pressed: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
can_dodge = true
|
||||
_init_input_events()
|
||||
_init_state_machine()
|
||||
death.connect(func(): remove_from_group(&"player"))
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_echo():
|
||||
return
|
||||
if event.is_action_pressed("attack"):
|
||||
attack_pressed = true
|
||||
_process_attack_input()
|
||||
if event.is_action_pressed("dodge"):
|
||||
hsm.dispatch("dodge!")
|
||||
|
||||
|
||||
func _process_attack_input() -> void:
|
||||
if not attack_pressed or hsm.get_active_state() == attack_state:
|
||||
return
|
||||
hsm.dispatch("attack!")
|
||||
attack_pressed = false
|
||||
|
||||
|
||||
func _init_state_machine() -> void:
|
||||
hsm.add_transition(idle_state, move_state, idle_state.EVENT_FINISHED)
|
||||
hsm.add_transition(move_state, idle_state, move_state.EVENT_FINISHED)
|
||||
hsm.add_transition(idle_state, attack_state, "attack!")
|
||||
hsm.add_transition(move_state, attack_state, "attack!")
|
||||
hsm.add_transition(attack_state, move_state, attack_state.EVENT_FINISHED)
|
||||
hsm.add_transition(hsm.ANYSTATE, dodge_state, "dodge!")
|
||||
hsm.add_transition(dodge_state, move_state, dodge_state.EVENT_FINISHED)
|
||||
|
||||
dodge_state.set_guard(_can_dodge)
|
||||
attack_state.set_guard(attack_state.can_enter)
|
||||
|
||||
# Process attack input buffer when move_state is entered.
|
||||
# This way we can buffer the attack button presses and chain the attacks.
|
||||
move_state.call_on_enter(_process_attack_input)
|
||||
|
||||
hsm.initialize(self)
|
||||
hsm.set_active(true)
|
||||
|
||||
|
||||
func _init_input_events() -> void:
|
||||
# Note: Ensures that input events are present even if project.godot wasn't imported.
|
||||
_add_action(&"move_left", KEY_A)
|
||||
_add_action(&"move_right", KEY_D)
|
||||
_add_action(&"move_up", KEY_W)
|
||||
_add_action(&"move_down", KEY_S)
|
||||
_add_action(&"dodge", KEY_SPACE)
|
||||
_add_action(&"attack", KEY_ENTER, KEY_F)
|
||||
|
||||
|
||||
func _add_action(p_action: StringName, p_key: Key, p_alt: Key = KEY_NONE) -> void:
|
||||
if not InputMap.has_action(p_action):
|
||||
InputMap.add_action(p_action)
|
||||
var event := InputEventKey.new()
|
||||
event.keycode = p_key
|
||||
InputMap.action_add_event(p_action, event)
|
||||
if p_alt != KEY_NONE:
|
||||
var alt := InputEventKey.new()
|
||||
alt.keycode = p_alt
|
||||
InputMap.action_add_event(p_action, alt)
|
||||
|
||||
|
||||
func set_victorious() -> void:
|
||||
idle_state.idle_animation = &"dance"
|
||||
|
||||
|
||||
func _can_dodge() -> bool:
|
||||
if can_dodge:
|
||||
can_dodge = false
|
||||
get_tree().create_timer(dodge_cooldown).timeout.connect(func(): can_dodge = true)
|
||||
return true
|
||||
return false
|
||||
53
demo/agents/player/player.tscn
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
[gd_scene load_steps=8 format=3 uid="uid://d07ag5dcje13i"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_mswd4"]
|
||||
[ext_resource type="Script" path="res://demo/agents/player/player.gd" id="2_24nyi"]
|
||||
[ext_resource type="Script" path="res://demo/agents/player/states/idle_state.gd" id="3_ekb12"]
|
||||
[ext_resource type="Script" path="res://demo/agents/player/states/move_state.gd" id="4_paikn"]
|
||||
[ext_resource type="Script" path="res://demo/agents/player/states/attack_state.gd" id="5_mpgu6"]
|
||||
[ext_resource type="Script" path="res://demo/agents/player/states/dodge_state.gd" id="6_7o4a6"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_8pofm"]
|
||||
size = Vector2(150, 50)
|
||||
|
||||
[node name="Player" groups=["player"] instance=ExtResource("1_mswd4")]
|
||||
collision_layer = 0
|
||||
collision_mask = 1
|
||||
script = ExtResource("2_24nyi")
|
||||
dodge_cooldown = 0.4
|
||||
|
||||
[node name="Hitbox" parent="Root" index="1"]
|
||||
collision_mask = 8
|
||||
|
||||
[node name="HitboxCollisionShape2D" parent="Root/Hitbox" index="0"]
|
||||
shape = SubResource("RectangleShape2D_8pofm")
|
||||
|
||||
[node name="Hurtbox" parent="Root" index="2"]
|
||||
collision_layer = 4
|
||||
|
||||
[node name="Health" parent="." index="3"]
|
||||
max_health = 30.0
|
||||
|
||||
[node name="LimboHSM" type="LimboHSM" parent="." index="4"]
|
||||
|
||||
[node name="IdleState" type="LimboState" parent="LimboHSM" index="0" node_paths=PackedStringArray("animation_player")]
|
||||
script = ExtResource("3_ekb12")
|
||||
animation_player = NodePath("../../AnimationPlayer")
|
||||
idle_animation = &"idle"
|
||||
|
||||
[node name="MoveState" type="LimboState" parent="LimboHSM" index="1" node_paths=PackedStringArray("animation_player")]
|
||||
script = ExtResource("4_paikn")
|
||||
animation_player = NodePath("../../AnimationPlayer")
|
||||
animation = &"walk"
|
||||
|
||||
[node name="AttackState" type="LimboState" parent="LimboHSM" index="2" node_paths=PackedStringArray("animation_player", "hitbox")]
|
||||
script = ExtResource("5_mpgu6")
|
||||
animation_player = NodePath("../../AnimationPlayer")
|
||||
animations = Array[StringName]([&"attack_1", &"attack_2", &"attack_3"])
|
||||
hitbox = NodePath("../../Root/Hitbox")
|
||||
|
||||
[node name="DodgeState" type="LimboState" parent="LimboHSM" index="3" node_paths=PackedStringArray("animation_player", "hurtbox_collision")]
|
||||
script = ExtResource("6_7o4a6")
|
||||
animation_player = NodePath("../../AnimationPlayer")
|
||||
animation = &"dodge"
|
||||
hurtbox_collision = NodePath("../../Root/Hurtbox/HurtboxCollisionShape2D")
|
||||
60
demo/agents/player/states/attack_state.gd
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#*
|
||||
#* attack_state.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends LimboState
|
||||
|
||||
## Attack state: Perform 3-part combo attack for as long as player hits attack button.
|
||||
|
||||
@export var animation_player: AnimationPlayer
|
||||
@export var animations: Array[StringName]
|
||||
@export var hitbox: Hitbox
|
||||
|
||||
## Cooldown duration after third attack in the combo is complete.
|
||||
@export var combo_cooldown: float = 0.1
|
||||
|
||||
var anim_index: int = 0
|
||||
var last_attack_msec: int = -10000
|
||||
var _can_enter: bool = true
|
||||
|
||||
|
||||
## This func is used to prevent entering this state using LimboState.set_guard().
|
||||
## Entry is denied for a short duration after the third attack in the combo is complete.
|
||||
func can_enter() -> bool:
|
||||
return _can_enter
|
||||
|
||||
|
||||
func _enter() -> void:
|
||||
if (Time.get_ticks_msec() - last_attack_msec) < 200:
|
||||
# Perform next attack animation in the 3-part combo, if an attack was recently performed.
|
||||
anim_index = (anim_index + 1) % 3
|
||||
else:
|
||||
anim_index = 0
|
||||
|
||||
var horizontal_move: float = Input.get_axis(&"move_left", &"move_right")
|
||||
if not is_zero_approx(horizontal_move):
|
||||
agent.face_dir(horizontal_move)
|
||||
|
||||
hitbox.damage = 2 if anim_index == 2 else 1 # deal 2 damage on a third attack in the combo
|
||||
animation_player.play(animations[anim_index])
|
||||
|
||||
await animation_player.animation_finished
|
||||
if is_active():
|
||||
get_root().dispatch(EVENT_FINISHED)
|
||||
|
||||
|
||||
func _exit() -> void:
|
||||
hitbox.damage = 1
|
||||
last_attack_msec = Time.get_ticks_msec()
|
||||
if anim_index == 2 and _can_enter:
|
||||
# Prevent entering this state for a short duration after the third attack
|
||||
# in the combo sequence is complete.
|
||||
_can_enter = false
|
||||
await get_tree().create_timer(combo_cooldown).timeout
|
||||
_can_enter = true
|
||||
48
demo/agents/player/states/dodge_state.gd
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#*
|
||||
#* dodge_state.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends LimboState
|
||||
## Dodge state.
|
||||
|
||||
|
||||
@export var animation_player: AnimationPlayer
|
||||
@export var animation: StringName
|
||||
@export var duration: float = 0.4
|
||||
@export var dodge_speed: float = 1000.0
|
||||
@export var hurtbox_collision: CollisionShape2D
|
||||
|
||||
var move_dir: Vector2
|
||||
var elapsed_time: float
|
||||
|
||||
|
||||
func _enter() -> void:
|
||||
elapsed_time = 0.0
|
||||
hurtbox_collision.disabled = true
|
||||
|
||||
var horizontal_move: float = Input.get_axis(&"move_left", &"move_right")
|
||||
if is_zero_approx(horizontal_move):
|
||||
move_dir = Vector2.RIGHT * agent.get_facing()
|
||||
else:
|
||||
move_dir = Vector2.RIGHT * signf(horizontal_move)
|
||||
agent.face_dir(move_dir.x)
|
||||
|
||||
animation_player.play(animation, 0.1)
|
||||
|
||||
|
||||
func _exit() -> void:
|
||||
hurtbox_collision.set_deferred(&"disabled", false)
|
||||
|
||||
|
||||
func _update(p_delta: float) -> void:
|
||||
elapsed_time += p_delta
|
||||
var desired_velocity: Vector2 = move_dir * dodge_speed
|
||||
agent.move(desired_velocity)
|
||||
if elapsed_time > duration:
|
||||
get_root().dispatch(EVENT_FINISHED)
|
||||
27
demo/agents/player/states/idle_state.gd
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#*
|
||||
#* idle_state.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends LimboState
|
||||
## Idle state.
|
||||
|
||||
|
||||
@export var animation_player: AnimationPlayer
|
||||
@export var idle_animation: StringName
|
||||
|
||||
|
||||
func _enter() -> void:
|
||||
animation_player.play(idle_animation, 0.1)
|
||||
|
||||
|
||||
func _update(_delta: float) -> void:
|
||||
var horizontal_move: float = Input.get_axis(&"move_left", &"move_right")
|
||||
var vertical_move: float = Input.get_axis(&"move_up", &"move_down")
|
||||
if horizontal_move != 0.0 or vertical_move != 0.0:
|
||||
get_root().dispatch(EVENT_FINISHED)
|
||||
37
demo/agents/player/states/move_state.gd
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#*
|
||||
#* move_state.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends LimboState
|
||||
## Move state.
|
||||
|
||||
|
||||
const VERTICAL_FACTOR := 0.8
|
||||
|
||||
@export var animation_player: AnimationPlayer
|
||||
@export var animation: StringName
|
||||
@export var speed: float = 500.0
|
||||
|
||||
|
||||
func _enter() -> void:
|
||||
animation_player.play(animation, 0.1)
|
||||
|
||||
|
||||
func _update(_delta: float) -> void:
|
||||
var horizontal_move: float = Input.get_axis(&"move_left", &"move_right")
|
||||
var vertical_move: float = Input.get_axis(&"move_up", &"move_down")
|
||||
|
||||
if not is_zero_approx(horizontal_move):
|
||||
agent.face_dir(horizontal_move)
|
||||
|
||||
var desired_velocity := Vector2(horizontal_move, vertical_move * VERTICAL_FACTOR) * speed
|
||||
agent.move(desired_velocity)
|
||||
|
||||
if horizontal_move == 0.0 and vertical_move == 0.0:
|
||||
get_root().dispatch(EVENT_FINISHED)
|
||||
161
demo/agents/scripts/agent_base.gd
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
#*
|
||||
#* agent_base.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends CharacterBody2D
|
||||
## Base agent script that is shared by all agents.
|
||||
|
||||
signal death
|
||||
|
||||
# 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")
|
||||
|
||||
var summon_count: int = 0
|
||||
|
||||
var _frames_since_facing_update: int = 0
|
||||
var _is_dead: bool = false
|
||||
var _moved_this_frame: bool = false
|
||||
|
||||
@onready var animation_player: AnimationPlayer = $AnimationPlayer
|
||||
@onready var health: Health = $Health
|
||||
@onready var root: Node2D = $Root
|
||||
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
|
||||
@onready var summoning_effect: GPUParticles2D = $FX/Summoned
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
health.damaged.connect(_damaged)
|
||||
health.death.connect(die)
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
_post_physics_process.call_deferred()
|
||||
|
||||
|
||||
func _post_physics_process() -> void:
|
||||
if not _moved_this_frame:
|
||||
velocity = lerp(velocity, Vector2.ZERO, 0.5)
|
||||
_moved_this_frame = false
|
||||
|
||||
|
||||
func move(p_velocity: Vector2) -> void:
|
||||
velocity = lerp(velocity, p_velocity, 0.2)
|
||||
move_and_slide()
|
||||
_moved_this_frame = true
|
||||
|
||||
|
||||
## 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;
|
||||
_frames_since_facing_update = 0
|
||||
if dir < 0.0 and root.scale.x > 0.0:
|
||||
root.scale.x = -1.0;
|
||||
_frames_since_facing_update = 0
|
||||
|
||||
## Returns 1.0 when agent is facing right.
|
||||
## Returns -1.0 when agent is facing left.
|
||||
func get_facing() -> float:
|
||||
return signf(root.scale.x)
|
||||
|
||||
|
||||
func throw_ninja_star() -> void:
|
||||
var ninja_star := NinjaStar.instantiate()
|
||||
ninja_star.dir = get_facing()
|
||||
get_parent().add_child(ninja_star)
|
||||
ninja_star.global_position = global_position + Vector2.RIGHT * 100.0 * get_facing()
|
||||
|
||||
|
||||
func spit_fire() -> void:
|
||||
var fireball := Fireball.instantiate()
|
||||
fireball.dir = get_facing()
|
||||
get_parent().add_child(fireball)
|
||||
fireball.global_position = global_position + Vector2.RIGHT * 100.0 * get_facing()
|
||||
|
||||
|
||||
func summon_minion(p_position: Vector2) -> void:
|
||||
var minion: CharacterBody2D = load(MINION_RESOURCE).instantiate()
|
||||
get_parent().add_child(minion)
|
||||
minion.position = p_position
|
||||
minion.play_summoning_effect()
|
||||
summon_count += 1
|
||||
minion.death.connect(func(): summon_count -= 1)
|
||||
|
||||
|
||||
## Method is used when this agent is summoned from the dungeons of the castle AaaAaaAAAAAaaAAaaaaaa
|
||||
func play_summoning_effect() -> void:
|
||||
summoning_effect.emitting = true
|
||||
|
||||
|
||||
## Is specified position inside the arena (not inside an obstacle)?
|
||||
func is_good_position(p_position: Vector2) -> bool:
|
||||
var space_state := get_world_2d().direct_space_state
|
||||
var params := PhysicsPointQueryParameters2D.new()
|
||||
params.position = p_position
|
||||
params.collision_mask = 1 # Obstacle layer has value 1
|
||||
var collision := space_state.intersect_point(params)
|
||||
return collision.is_empty()
|
||||
|
||||
|
||||
## When agent is damaged...
|
||||
func _damaged(_amount: float, knockback: Vector2) -> void:
|
||||
apply_knockback(knockback)
|
||||
animation_player.play(&"hurt")
|
||||
var btplayer := get_node_or_null(^"BTPlayer") as BTPlayer
|
||||
if btplayer:
|
||||
btplayer.set_active(false)
|
||||
var hsm := get_node_or_null(^"LimboHSM")
|
||||
if hsm:
|
||||
hsm.set_active(false)
|
||||
await animation_player.animation_finished
|
||||
if btplayer and not _is_dead:
|
||||
btplayer.restart()
|
||||
if hsm and not _is_dead:
|
||||
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
|
||||
for i in range(frames):
|
||||
move(knockback)
|
||||
await get_tree().physics_frame
|
||||
|
||||
|
||||
func die() -> void:
|
||||
if _is_dead:
|
||||
return
|
||||
death.emit()
|
||||
_is_dead = true
|
||||
root.process_mode = Node.PROCESS_MODE_DISABLED
|
||||
animation_player.play(&"death")
|
||||
collision_shape_2d.set_deferred(&"disabled", true)
|
||||
|
||||
for child in get_children():
|
||||
if child is BTPlayer or child is LimboHSM:
|
||||
child.set_active(false)
|
||||
|
||||
if get_tree():
|
||||
await get_tree().create_timer(10.0).timeout
|
||||
queue_free()
|
||||
|
||||
|
||||
func get_health() -> Health:
|
||||
return health
|
||||
46
demo/agents/scripts/health.gd
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#*
|
||||
#* health.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
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
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_current = max_health
|
||||
|
||||
|
||||
func take_damage(amount: float, knockback: Vector2) -> void:
|
||||
if _current <= 0.0:
|
||||
return
|
||||
|
||||
_current -= amount
|
||||
_current = max(_current, 0.0)
|
||||
|
||||
if _current <= 0.0:
|
||||
death.emit()
|
||||
else:
|
||||
damaged.emit(amount, knockback)
|
||||
|
||||
|
||||
## Returns current health.
|
||||
func get_current() -> float:
|
||||
return _current
|
||||
39
demo/agents/scripts/hitbox.gd
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#*
|
||||
#* hitbox.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
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)
|
||||
|
||||
|
||||
func _area_entered(hurtbox: Hurtbox) -> void:
|
||||
if hurtbox.owner == owner:
|
||||
return
|
||||
hurtbox.take_damage(damage, get_knockback(), self)
|
||||
|
||||
|
||||
func get_knockback() -> Vector2:
|
||||
var knockback: Vector2
|
||||
if knockback_enabled:
|
||||
knockback = Vector2.RIGHT.rotated(global_rotation) * knockback_strength
|
||||
return knockback
|
||||
22
demo/agents/scripts/hurtbox.gd
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#*
|
||||
#* hurtbox.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
class_name Hurtbox
|
||||
extends Area2D
|
||||
## Area that registers damage.
|
||||
|
||||
@export var health: Health
|
||||
|
||||
var last_attack_vector: Vector2
|
||||
|
||||
|
||||
func take_damage(amount: float, knockback: Vector2, source: Hitbox) -> void:
|
||||
last_attack_vector = owner.global_position - source.owner.global_position
|
||||
health.take_damage(amount, knockback)
|
||||
31
demo/agents/tutorial/tutorial_01_welcome.tscn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://dk67yawiu33jv"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_2vrmp"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_3h4dj"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://b1mfh8yad7rmw" path="res://demo/ai/trees/tutorial/tutorial_01_welcome.tres" id="3_ilmgw"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"]
|
||||
|
||||
[node name="TutorialWelcome" instance=ExtResource("1_2vrmp")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_3h4dj")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_3h4dj")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_3h4dj")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_3h4dj")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_3h4dj")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_3h4dj")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_ilmgw")
|
||||
blackboard_plan = SubResource("BlackboardPlan_52mdk")
|
||||
31
demo/agents/tutorial/tutorial_02_introduction.tscn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://cw3yth564nhrw"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_lia2k"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_4x2l4"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://b1i0xo0o676va" path="res://demo/ai/trees/tutorial/tutorial_02_introduction.tres" id="3_3esuy"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"]
|
||||
|
||||
[node name="TutorialIntro" instance=ExtResource("1_lia2k")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_4x2l4")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_4x2l4")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_4x2l4")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_4x2l4")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_4x2l4")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_4x2l4")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_3esuy")
|
||||
blackboard_plan = SubResource("BlackboardPlan_52mdk")
|
||||
31
demo/agents/tutorial/tutorial_03_types.tscn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://bx4iabilsv3rs"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_p8nwq"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_hnwhw"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://cb0ybf24ahnc3" path="res://demo/ai/trees/tutorial/tutorial_03_types.tres" id="3_a31ka"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"]
|
||||
|
||||
[node name="TutorialTypes" instance=ExtResource("1_p8nwq")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_hnwhw")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_hnwhw")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_hnwhw")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_hnwhw")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_hnwhw")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_hnwhw")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_a31ka")
|
||||
blackboard_plan = SubResource("BlackboardPlan_52mdk")
|
||||
31
demo/agents/tutorial/tutorial_04_sequence.tscn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://bhtm8gnk5hsus"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_oibr1"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_j52yc"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://dln8ywvtqedt7" path="res://demo/ai/trees/tutorial/tutorial_04_sequence.tres" id="3_feewj"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"]
|
||||
|
||||
[node name="TutorialSequence" instance=ExtResource("1_oibr1")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_j52yc")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_j52yc")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_j52yc")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_j52yc")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_j52yc")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_j52yc")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_feewj")
|
||||
blackboard_plan = SubResource("BlackboardPlan_52mdk")
|
||||
31
demo/agents/tutorial/tutorial_05_selector.tscn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://5nqbasyipupf"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_62fs7"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_gdg2c"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://bf4r652fv5kwi" path="res://demo/ai/trees/tutorial/tutorial_05_selector.tres" id="3_pm5ep"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"]
|
||||
|
||||
[node name="TutorialSelector" instance=ExtResource("1_62fs7")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_gdg2c")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_gdg2c")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_gdg2c")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_gdg2c")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_gdg2c")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_gdg2c")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_pm5ep")
|
||||
blackboard_plan = SubResource("BlackboardPlan_52mdk")
|
||||
31
demo/agents/tutorial/tutorial_06_decorators.tscn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://ehc00upu3co"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_mbrnd"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_ttkri"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://beiki511huxb8" path="res://demo/ai/trees/tutorial/tutorial_06_decorators.tres" id="3_tpgll"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"]
|
||||
|
||||
[node name="TutorialDecorators" instance=ExtResource("1_mbrnd")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_ttkri")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_ttkri")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_ttkri")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_ttkri")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_ttkri")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_ttkri")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_tpgll")
|
||||
blackboard_plan = SubResource("BlackboardPlan_52mdk")
|
||||
31
demo/agents/tutorial/tutorial_07_more_decorators.tscn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://brq6c843j1eeo"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_k4qfc"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_q4r1n"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://tep50j4d6kgp" path="res://demo/ai/trees/tutorial/tutorial_07_more_decorators.tres" id="3_ta3g6"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"]
|
||||
|
||||
[node name="TutorialMoreDecorators" instance=ExtResource("1_k4qfc")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_q4r1n")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_q4r1n")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_q4r1n")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_q4r1n")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_q4r1n")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_q4r1n")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_ta3g6")
|
||||
blackboard_plan = SubResource("BlackboardPlan_52mdk")
|
||||
31
demo/agents/tutorial/tutorial_08_final_touch.tscn
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://b8yj40s43bw8h"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_bjdsc"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_onjfd"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://dp0cglcytwcj5" path="res://demo/ai/trees/tutorial/tutorial_08_final_touch.tres" id="3_c5qx4"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"]
|
||||
|
||||
[node name="TutorialFinalTouch" instance=ExtResource("1_bjdsc")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_onjfd")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_onjfd")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_onjfd")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
texture = ExtResource("2_onjfd")
|
||||
|
||||
[node name="HandL" parent="Root/Rig/Body" index="1"]
|
||||
texture = ExtResource("2_onjfd")
|
||||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_onjfd")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_c5qx4")
|
||||
blackboard_plan = SubResource("BlackboardPlan_52mdk")
|
||||
69
demo/ai/tasks/arrive_pos.gd
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#*
|
||||
#* arrive_pos.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Moves the agent to the specified position, favoring horizontal movement. [br]
|
||||
## Returns [code]SUCCESS[/code] when close to the target position (see [member tolerance]);
|
||||
## otherwise returns [code]RUNNING[/code].
|
||||
|
||||
## 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
|
||||
|
||||
## Specifies the node to avoid (valid Node2D is expected).
|
||||
## If not empty, agent will circle around the node while moving into position.
|
||||
@export var avoid_var: StringName
|
||||
|
||||
|
||||
func _generate_name() -> String:
|
||||
return "Arrive pos: %s%s" % [
|
||||
LimboUtility.decorate_var(target_position_var),
|
||||
"" if avoid_var.is_empty() else " avoid: " + LimboUtility.decorate_var(avoid_var)
|
||||
]
|
||||
|
||||
|
||||
func _tick(_delta: float) -> Status:
|
||||
var target_pos: Vector2 = blackboard.get_var(target_position_var, Vector2.ZERO)
|
||||
if target_pos.distance_to(agent.global_position) < tolerance:
|
||||
return SUCCESS
|
||||
|
||||
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)
|
||||
dir.y *= vertical_factor
|
||||
|
||||
# Avoid the node specified by `avoid_var`.
|
||||
# I.e., if `avoid_var` is set, agent will circle around that node while moving into position.
|
||||
if not avoid_var.is_empty():
|
||||
var avoid_node: Node2D = blackboard.get_var(avoid_var)
|
||||
if is_instance_valid(avoid_node):
|
||||
var distance_vector: Vector2 = avoid_node.global_position - agent.global_position
|
||||
if dir.dot(distance_vector) > 0.0:
|
||||
var side := dir.rotated(PI * 0.5).normalized()
|
||||
# The closer we are to the avoid target, the stronger is the avoidance.
|
||||
var strength: float = remap(distance_vector.length(), 200.0, 400.0, 1.0, 0.0)
|
||||
strength = clampf(strength, 0.0, 1.0)
|
||||
var avoidance := side * signf(-side.dot(distance_vector)) * strength
|
||||
dir += avoidance
|
||||
|
||||
var desired_velocity: Vector2 = dir.normalized() * speed
|
||||
agent.move(desired_velocity)
|
||||
agent.update_facing()
|
||||
return RUNNING
|
||||
39
demo/ai/tasks/back_away.gd
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#*
|
||||
#* back_away.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Moves the agent in the opposite direction of its current facing. [br]
|
||||
## Returns [code]RUNNING[/code] always.
|
||||
|
||||
## Blackboard variable that stores desired speed.
|
||||
@export var speed_var: StringName = &"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)
|
||||
_desired_velocity = _dir.rotated(rand_angle) * speed
|
||||
|
||||
|
||||
# Called each time this task is ticked (aka executed).
|
||||
func _tick(_delta: float) -> Status:
|
||||
agent.move(_desired_velocity)
|
||||
agent.face_dir(-signf(_dir.x))
|
||||
return RUNNING
|
||||
32
demo/ai/tasks/face_target.gd
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#*
|
||||
#* face_target.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Flips the agent to face the target, returning [code]SUCCESS[/code]. [br]
|
||||
## Returns [code]FAILURE[/code] if [member target_var] is not a valid [Node2D] instance.
|
||||
|
||||
## Blackboard variable that stores our target (expecting Node2D).
|
||||
@export var target_var: StringName = &"target"
|
||||
|
||||
# Display a customized name (requires @tool).
|
||||
func _generate_name() -> String:
|
||||
return "FaceTarget " + LimboUtility.decorate_var(target_var)
|
||||
|
||||
|
||||
# Called each time this task is ticked (aka executed).
|
||||
func _tick(_delta: float) -> Status:
|
||||
var target: Node2D = blackboard.get_var(target_var)
|
||||
if not is_instance_valid(target):
|
||||
return FAILURE
|
||||
var dir: float = target.global_position.x - agent.global_position.x
|
||||
agent.velocity = Vector2.ZERO
|
||||
agent.face_dir(dir)
|
||||
return SUCCESS
|
||||
34
demo/ai/tasks/get_first_in_group.gd
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#*
|
||||
#* get_first_in_group.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Stores the first node in the [member group] on the blackboard, returning [code]SUCCESS[/code]. [br]
|
||||
## Returns [code]FAILURE[/code] if the 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: StringName = &"target"
|
||||
|
||||
|
||||
func _generate_name() -> String:
|
||||
return "GetFirstNodeInGroup \"%s\" ➜%s" % [
|
||||
group,
|
||||
LimboUtility.decorate_var(output_var)
|
||||
]
|
||||
|
||||
func _tick(_delta: float) -> Status:
|
||||
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
|
||||
54
demo/ai/tasks/in_range.gd
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#*
|
||||
#* in_range.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTCondition
|
||||
## InRange condition checks if the agent is within a range of target,
|
||||
## defined by [member distance_min] and [member distance_max]. [br]
|
||||
## Returns [code]SUCCESS[/code] if the agent is within the given range;
|
||||
## otherwise, returns [code]FAILURE[/code].
|
||||
|
||||
## 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: StringName = &"target"
|
||||
|
||||
var _min_distance_squared: float
|
||||
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)]
|
||||
|
||||
|
||||
# Called to initialize the task.
|
||||
func _setup() -> void:
|
||||
## 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 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
|
||||
35
demo/ai/tasks/is_aligned_with_target.gd
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#*
|
||||
#* is_aligned_with_target.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTCondition
|
||||
## Checks if the agent is horizontally aligned with the target. [br]
|
||||
## Returns [code]SUCCESS[/code] if the agent is horizontally aligned with the target.
|
||||
## Returns [code]FAILURE[/code] if not aligned or if target is not a valid node instance.
|
||||
|
||||
|
||||
@export var target_var: StringName = &"target"
|
||||
@export var tolerance: float = 30.0
|
||||
|
||||
|
||||
# Display a customized name (requires @tool).
|
||||
func _generate_name() -> String:
|
||||
return "IsAlignedWithTarget " + LimboUtility.decorate_var(target_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 y_diff: float = absf(target.global_position.y - agent.global_position.y)
|
||||
if y_diff < tolerance:
|
||||
return SUCCESS
|
||||
return FAILURE
|
||||
39
demo/ai/tasks/move_forward.gd
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#*
|
||||
#* move_forward.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Applies velocity in the direction the agent is facing on each tick
|
||||
## until the [member duration] is exceeded. [br]
|
||||
## Returns [code]SUCCESS[/code] if the elapsed time exceeds [member duration]. [br]
|
||||
## Returns [code]RUNNING[/code] if the elapsed time does not exceed [member duration]. [br]
|
||||
|
||||
## Blackboard variable that stores desired speed.
|
||||
@export var speed_var: StringName = &"speed"
|
||||
|
||||
## 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 "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 speed: float = blackboard.get_var(speed_var, 100.0)
|
||||
var desired_velocity: Vector2 = Vector2.RIGHT * facing * speed
|
||||
agent.move(desired_velocity)
|
||||
agent.update_facing()
|
||||
if elapsed_time > duration:
|
||||
return SUCCESS
|
||||
return RUNNING
|
||||
79
demo/ai/tasks/pursue.gd
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#*
|
||||
#* pursue.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Move towards the target until the agent is flanking it. [br]
|
||||
## Returns [code]RUNNING[/code] while moving towards the target but not yet at the desired position. [br]
|
||||
## Returns [code]SUCCESS[/code] when at the desired position relative to the target (flanking it). [br]
|
||||
## Returns [code]FAILURE[/code] if the target is not a valid [Node2D] instance. [br]
|
||||
|
||||
## 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: StringName = &"target"
|
||||
|
||||
## Blackboard variable that stores desired speed.
|
||||
@export var speed_var: StringName = &"speed"
|
||||
|
||||
## Desired distance from target.
|
||||
@export var approach_distance: float = 100.0
|
||||
|
||||
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))
|
||||
|
||||
|
||||
# Called each time this task is ticked (aka executed).
|
||||
func _tick(_delta: float) -> Status:
|
||||
var target: Node2D = blackboard.get_var(target_var, null)
|
||||
if not is_instance_valid(target):
|
||||
return FAILURE
|
||||
|
||||
var desired_pos: Vector2 = _get_desired_position(target)
|
||||
if agent.global_position.distance_to(desired_pos) < TOLERANCE:
|
||||
return SUCCESS
|
||||
|
||||
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.move(desired_velocity)
|
||||
agent.update_facing()
|
||||
return RUNNING
|
||||
|
||||
|
||||
## 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
|
||||
desired_pos.x += approach_distance * side
|
||||
return desired_pos
|
||||
|
||||
|
||||
## Select an intermidiate waypoint towards the desired position.
|
||||
func _select_new_waypoint(desired_position: Vector2) -> void:
|
||||
var distance_vector: Vector2 = desired_position - agent.global_position
|
||||
var angle_variation: float = randf_range(-0.2, 0.2)
|
||||
_waypoint = agent.global_position + distance_vector.limit_length(150.0).rotated(angle_variation)
|
||||
74
demo/ai/tasks/select_flanking_pos.gd
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#*
|
||||
#* select_flanking_pos.gd
|
||||
#* =============================================================================
|
||||
#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Selects a position on the target's side and stores it on the
|
||||
## blackboard, returning [code]SUCCESS[/code]. [br]
|
||||
## Returns [code]FAILURE[/code] if the target is not valid.
|
||||
|
||||
enum AgentSide {
|
||||
CLOSEST,
|
||||
FARTHEST,
|
||||
BACK,
|
||||
FRONT,
|
||||
}
|
||||
|
||||
## Blackboard variable that holds current target (should be a Node2D instance).
|
||||
@export var target_var: StringName = &"target"
|
||||
|
||||
## Which agent's side should we flank?
|
||||
@export var flank_side: AgentSide = AgentSide.CLOSEST
|
||||
|
||||
## Minimum range relative to the target.
|
||||
@export var range_min: int = 300
|
||||
|
||||
## Maximum range relative to the target.
|
||||
@export var range_max: int = 400
|
||||
|
||||
## Blackboard variable that will be used to store selected position.
|
||||
@export var position_var: StringName = &"pos"
|
||||
|
||||
|
||||
# Display a customized name (requires @tool).
|
||||
func _generate_name() -> String:
|
||||
return "SelectFlankingPos target: %s range: [%s, %s] side: %s ➜%s" % [
|
||||
LimboUtility.decorate_var(target_var),
|
||||
range_min,
|
||||
range_max,
|
||||
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 # 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 :
|
||||
dir = -signf(target.global_position.x - agent.global_position.x)
|
||||
AgentSide.BACK:
|
||||
dir = -target.get_facing()
|
||||
AgentSide.FRONT:
|
||||
dir = target.get_facing()
|
||||
|
||||
var flank_pos: Vector2
|
||||
var offset := Vector2(dir * randf_range(range_min, range_max), 0.0)
|
||||
flank_pos = target.global_position + offset
|
||||
if not agent.is_good_position(flank_pos):
|
||||
# Choose the opposite side if the preferred side is not good (i.e., inside a collision shape).
|
||||
flank_pos = target.global_position - offset
|
||||
blackboard.set_var(position_var, flank_pos)
|
||||
return SUCCESS
|
||||
34
demo/ai/tasks/select_random_nearby_pos.gd
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
@tool
|
||||
extends BTAction
|
||||
## Selects a random position nearby within the specified range and stores it on the blackboard. [br]
|
||||
## Returns [code]SUCCESS[/code].
|
||||
|
||||
## 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: StringName = &"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 (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
|
||||
is_good_position = agent.is_good_position(pos)
|
||||
blackboard.set_var(position_var, pos)
|
||||
return SUCCESS
|
||||
88
demo/ai/trees/01_agent_melee_simple.tres
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=21 format=3 uid="uid://bpdm5jnegi38"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_2jpsu"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/pursue.gd" id="2_h5db5"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="3_bpmfp"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_nrd4b"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
|
||||
animation_player = SubResource("BBNode_nrd4b")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"]
|
||||
min_duration = 0.7
|
||||
max_duration = 1.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_yhjh1"]
|
||||
custom_name = "Pause before action"
|
||||
children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_wpj6d"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"]
|
||||
animation_player = SubResource("BBNode_wpj6d")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ulbrf"]
|
||||
script = ExtResource("1_2jpsu")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_a4jqi"]
|
||||
script = ExtResource("2_h5db5")
|
||||
target_var = &"target"
|
||||
speed_var = &"speed"
|
||||
approach_distance = 100.0
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"]
|
||||
time_limit = 2.0
|
||||
children = [SubResource("BTAction_a4jqi")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_1xfnq"]
|
||||
custom_name = "Pursue player"
|
||||
children = [SubResource("BTPlayAnimation_olf37"), SubResource("BTAction_ulbrf"), SubResource("BTTimeLimit_xek5v")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_kidxn"]
|
||||
script = ExtResource("3_bpmfp")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_tadkc"]
|
||||
duration = 0.1
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_s8evu"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_s8evu")
|
||||
animation_name = &"attack_1"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_ww5v2"]
|
||||
custom_name = "Melee attack"
|
||||
children = [SubResource("BTAction_kidxn"), SubResource("BTWait_tadkc"), SubResource("BTPlayAnimation_ppmxd")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_pxl2k"]
|
||||
children = [SubResource("BTSequence_yhjh1"), SubResource("BTSequence_1xfnq"), SubResource("BTSequence_ww5v2")]
|
||||
|
||||
[resource]
|
||||
description = "Welcome to the [b]LimboAI[/b] demo project! This demo project consists of three parts:
|
||||
- If you're new to behavior trees, you can access the [b]Tutorial[/b] by clicking the \"Begin Tutorial\" button on the toolbar.
|
||||
- To experience the demo game, just click the \"Switch to Game\" button.
|
||||
- On this screen, you can inspect the AI behavior tree in action for each agent in the game."
|
||||
blackboard_plan = SubResource("BlackboardPlan_46tbn")
|
||||
root_task = SubResource("BTSequence_pxl2k")
|
||||
120
demo/ai/trees/02_agent_charger.tres
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=28 format=3 uid="uid://ylife72ym5et"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_657p6"]
|
||||
[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/move_forward.gd" id="5_ucvak"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_qd806"]
|
||||
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 = 1
|
||||
var/charge_speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_yrurg"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ha2ag"]
|
||||
animation_player = SubResource("BBNode_yrurg")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_cedqr"]
|
||||
max_duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_l3v31"]
|
||||
custom_name = "Short break"
|
||||
children = [SubResource("BTPlayAnimation_ha2ag"), SubResource("BTRandomWait_cedqr")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_pp23y"]
|
||||
script = ExtResource("1_657p6")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_pmvd0"]
|
||||
script = ExtResource("2_t3udh")
|
||||
target_var = &"target"
|
||||
flank_side = 0
|
||||
range_min = 500
|
||||
range_max = 600
|
||||
position_var = &"flank_pos"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_xh3wr"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_h0poo"]
|
||||
animation_player = SubResource("BBNode_xh3wr")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_87mi0"]
|
||||
script = ExtResource("3_u2ra5")
|
||||
target_position_var = &"flank_pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_is5ag"]
|
||||
time_limit = 3.0
|
||||
children = [SubResource("BTAction_87mi0")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_p6pgg"]
|
||||
custom_name = "Flank target"
|
||||
children = [SubResource("BTAction_pp23y"), SubResource("BTAction_pmvd0"), SubResource("BTPlayAnimation_h0poo"), SubResource("BTTimeLimit_is5ag")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_q5g4a"]
|
||||
script = ExtResource("4_xwjl7")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_bfijg"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_4okoy"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_bfijg")
|
||||
animation_name = &"charge_prepare"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_ovu3r"]
|
||||
duration = 0.6
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_mde2g"]
|
||||
custom_name = "Anticipation"
|
||||
children = [SubResource("BTAction_q5g4a"), SubResource("BTPlayAnimation_4okoy"), SubResource("BTWait_ovu3r")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_kpp70"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_8s1wq"]
|
||||
animation_player = SubResource("BBNode_kpp70")
|
||||
animation_name = &"charge"
|
||||
blend = 0.05
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_o18uk"]
|
||||
script = ExtResource("5_ucvak")
|
||||
speed_var = &"charge_speed"
|
||||
duration = 1.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_8lur1"]
|
||||
custom_name = "Charge!"
|
||||
children = [SubResource("BTPlayAnimation_8s1wq"), SubResource("BTAction_o18uk")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_pjuov"]
|
||||
custom_name = "Charge Attack"
|
||||
children = [SubResource("BTSequence_l3v31"), SubResource("BTSequence_p6pgg"), SubResource("BTSequence_mde2g"), SubResource("BTSequence_8lur1")]
|
||||
|
||||
[resource]
|
||||
description = "A [dec]Decorator[/dec] is a type of task that typically has only one child. Decorators are commonly used to alter the behavior or status of their child task. In this behavior tree, the [dec]TimeLimit[/dec] decorator sets a maximum time for the [act]Arrive[/act] action to complete its work. If the child task exceeds this time limit without finishing, it will be aborted, and the TimeLimit decorator will return [FAILURE]."
|
||||
blackboard_plan = SubResource("BlackboardPlan_qd806")
|
||||
root_task = SubResource("BTSequence_pjuov")
|
||||
120
demo/ai/trees/03_agent_imp.tres
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=30 format=3 uid="uid://c2bxoo68ywb27"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_cdtqu"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="2_31fsn"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="3_y1r1a"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/pursue.gd" id="4_jlgat"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="5_o4ggh"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_3y70b"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_klk26"]
|
||||
animation_player = SubResource("BBNode_3y70b")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_chmiy"]
|
||||
script = ExtResource("1_cdtqu")
|
||||
range_min = 200.0
|
||||
range_max = 500.0
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_5kivl"]
|
||||
script = ExtResource("2_31fsn")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_k184c"]
|
||||
custom_name = "Chaotic Walk"
|
||||
children = [SubResource("BTPlayAnimation_klk26"), SubResource("BTAction_chmiy"), SubResource("BTAction_5kivl")]
|
||||
|
||||
[sub_resource type="BTProbability" id="BTProbability_ifsry"]
|
||||
children = [SubResource("BTSequence_k184c")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_nrd4b"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
|
||||
animation_player = SubResource("BBNode_nrd4b")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"]
|
||||
min_duration = 0.7
|
||||
max_duration = 1.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_n5ltc"]
|
||||
custom_name = "Pause before action"
|
||||
children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_wpj6d"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"]
|
||||
animation_player = SubResource("BBNode_wpj6d")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ulbrf"]
|
||||
script = ExtResource("3_y1r1a")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_a4jqi"]
|
||||
script = ExtResource("4_jlgat")
|
||||
target_var = &"target"
|
||||
speed_var = &"speed"
|
||||
approach_distance = 100.0
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"]
|
||||
time_limit = 2.0
|
||||
children = [SubResource("BTAction_a4jqi")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_1xfnq"]
|
||||
custom_name = "Pursue player"
|
||||
children = [SubResource("BTPlayAnimation_olf37"), SubResource("BTAction_ulbrf"), SubResource("BTTimeLimit_xek5v")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_kidxn"]
|
||||
script = ExtResource("5_o4ggh")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_tadkc"]
|
||||
duration = 0.1
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_s8evu"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_s8evu")
|
||||
animation_name = &"attack_1"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_ww5v2"]
|
||||
custom_name = "Melee attack"
|
||||
children = [SubResource("BTAction_kidxn"), SubResource("BTWait_tadkc"), SubResource("BTPlayAnimation_ppmxd")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_pxl2k"]
|
||||
custom_name = "Engage player"
|
||||
children = [SubResource("BTSequence_n5ltc"), SubResource("BTSequence_1xfnq"), SubResource("BTSequence_ww5v2")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_y3llm"]
|
||||
children = [SubResource("BTProbability_ifsry"), SubResource("BTSequence_pxl2k")]
|
||||
|
||||
[resource]
|
||||
description = "Here, the [dec]Probability[/dec] decorator allows the execution of its branch in 50% of cases. This introduces a slight variation to the behavior each time the [comp]Chaotic walk[/comp] sequence is considered by the [comp]Selector[/comp]. This sequence can be selected several times in a row as long as the Probability decorator permits it. The [comp]Engage player[/comp] sequence is only executed if Probability returns [FAILURE]."
|
||||
blackboard_plan = SubResource("BlackboardPlan_46tbn")
|
||||
root_task = SubResource("BTSelector_y3llm")
|
||||
190
demo/ai/trees/04_agent_skirmisher.tres
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=44 format=3 uid="uid://qqmjvbeibatn"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_2883n"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_cjso2"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/pursue.gd" id="2_lpckh"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="3_treio"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="4_57x51"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/in_range.gd" id="5_p5dih"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/back_away.gd" id="6_fkv0k"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"]
|
||||
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/fast_speed/name = &"fast_speed"
|
||||
var/fast_speed/type = 3
|
||||
var/fast_speed/value = 600.0
|
||||
var/fast_speed/hint = 1
|
||||
var/fast_speed/hint_string = "10,1000,10"
|
||||
var/slow_speed/name = &"slow_speed"
|
||||
var/slow_speed/type = 3
|
||||
var/slow_speed/value = 300.0
|
||||
var/slow_speed/hint = 1
|
||||
var/slow_speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ulbrf"]
|
||||
script = ExtResource("1_2883n")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_nrd4b"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
|
||||
animation_player = SubResource("BBNode_nrd4b")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"]
|
||||
min_duration = 2.0
|
||||
max_duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_yhjh1"]
|
||||
custom_name = "Summoning sickness"
|
||||
children = [SubResource("BTAction_ulbrf"), SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")]
|
||||
|
||||
[sub_resource type="BTRunLimit" id="BTRunLimit_tq3e1"]
|
||||
children = [SubResource("BTSequence_yhjh1")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_uk4dg"]
|
||||
script = ExtResource("5_p5dih")
|
||||
distance_min = 0.0
|
||||
distance_max = 300.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_7c0g0"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_sty80"]
|
||||
animation_player = SubResource("BBNode_7c0g0")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
speed = 1.2
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_jryg6"]
|
||||
script = ExtResource("2_lpckh")
|
||||
target_var = &"target"
|
||||
speed_var = &"speed"
|
||||
approach_distance = 100.0
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_lkphr"]
|
||||
time_limit = 1.0
|
||||
children = [SubResource("BTAction_jryg6")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_kidxn"]
|
||||
script = ExtResource("4_57x51")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_tadkc"]
|
||||
duration = 0.2
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_kcqly"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_hngi6"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_kcqly")
|
||||
animation_name = &"attack_3"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_cm8jy"]
|
||||
duration = 0.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_ww5v2"]
|
||||
custom_name = "Melee attack"
|
||||
children = [SubResource("BTCondition_uk4dg"), SubResource("BTPlayAnimation_sty80"), SubResource("BTTimeLimit_lkphr"), SubResource("BTAction_kidxn"), SubResource("BTWait_tadkc"), SubResource("BTPlayAnimation_hngi6"), SubResource("BTWait_cm8jy")]
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_ksvfy"]
|
||||
duration = 2.0
|
||||
children = [SubResource("BTSequence_ww5v2")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_fpufi"]
|
||||
script = ExtResource("5_p5dih")
|
||||
distance_min = 0.0
|
||||
distance_max = 300.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_3iqcf"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ee0ff"]
|
||||
animation_player = SubResource("BBNode_3iqcf")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
speed = -0.7
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_4ye2y"]
|
||||
script = ExtResource("6_fkv0k")
|
||||
speed_var = &"slow_speed"
|
||||
max_angle_deviation = 0.7
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_cns1i"]
|
||||
time_limit = 1.5
|
||||
children = [SubResource("BTAction_4ye2y")]
|
||||
|
||||
[sub_resource type="BTAlwaysSucceed" id="BTAlwaysSucceed_nw4ep"]
|
||||
children = [SubResource("BTTimeLimit_cns1i")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_81x7t"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_e61er"]
|
||||
animation_player = SubResource("BBNode_81x7t")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_jw0cm"]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_y12eg"]
|
||||
custom_name = "Disengage"
|
||||
children = [SubResource("BTCondition_fpufi"), SubResource("BTPlayAnimation_ee0ff"), SubResource("BTAlwaysSucceed_nw4ep"), SubResource("BTPlayAnimation_e61er"), SubResource("BTRandomWait_jw0cm")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_wpj6d"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"]
|
||||
animation_player = SubResource("BBNode_wpj6d")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
speed = 1.2
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_g5ayy"]
|
||||
script = ExtResource("2_cjso2")
|
||||
target_var = &"target"
|
||||
flank_side = 2
|
||||
range_min = 90
|
||||
range_max = 90
|
||||
position_var = &"flank_pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_tv4lt"]
|
||||
script = ExtResource("3_treio")
|
||||
target_position_var = &"flank_pos"
|
||||
speed_var = &"fast_speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &"target"
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"]
|
||||
children = [SubResource("BTAction_tv4lt")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_rgwic"]
|
||||
custom_name = "Flank from behind"
|
||||
children = [SubResource("BTPlayAnimation_olf37"), SubResource("BTAction_g5ayy"), SubResource("BTTimeLimit_xek5v")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_2jnau"]
|
||||
children = [SubResource("BTRunLimit_tq3e1"), SubResource("BTCooldown_ksvfy"), SubResource("BTSequence_y12eg"), SubResource("BTSequence_rgwic")]
|
||||
|
||||
[resource]
|
||||
description = "Like actions, conditions do not contain child tasks within them. Instead, they evaluate specific criteria and return either a [SUCCESS] or [FAILURE] based on the agent's or environment's state (for example, \"IsLowOnHealth\", \"IsTargetInSight\"). Conditions are commonly employed alongside sequences to interrupt their execution if a particular requirement is not met.
|
||||
|
||||
In our example, if the target is not within the specified range, the [con]InRange[/con] condition will return [FAILURE], causing the [comp]sequence[/comp] to be aborted.
|
||||
"
|
||||
blackboard_plan = SubResource("BlackboardPlan_46tbn")
|
||||
root_task = SubResource("BTSelector_2jnau")
|
||||
182
demo/ai/trees/05_agent_ranged.tres
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=41 format=3 uid="uid://cqluon1y1hnn5"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_4xk1i"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/is_aligned_with_target.gd" id="2_a8qex"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="3_q4r2p"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="4_53hao"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="5_aexyq"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"]
|
||||
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/run_speed/name = &"run_speed"
|
||||
var/run_speed/type = 3
|
||||
var/run_speed/value = 600.0
|
||||
var/run_speed/hint = 1
|
||||
var/run_speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_nrd4b"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
|
||||
animation_player = SubResource("BBNode_nrd4b")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"]
|
||||
min_duration = 0.7
|
||||
max_duration = 1.5
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_c4cxo"]
|
||||
script = ExtResource("1_4xk1i")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_yhjh1"]
|
||||
custom_name = "Take a break"
|
||||
children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8"), SubResource("BTAction_c4cxo")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_ok0r5"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_unftu"]
|
||||
animation_player = SubResource("BBNode_ok0r5")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
speed = 1.5
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_op6l6"]
|
||||
script = ExtResource("4_53hao")
|
||||
target_var = &"target"
|
||||
flank_side = 1
|
||||
range_min = 400
|
||||
range_max = 1000
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ycjun"]
|
||||
script = ExtResource("3_q4r2p")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"run_speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &"target"
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_gadc6"]
|
||||
time_limit = 7.0
|
||||
children = [SubResource("BTAction_ycjun")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_poqpu"]
|
||||
script = ExtResource("5_aexyq")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_0gdqn"]
|
||||
custom_name = "Change flank"
|
||||
children = [SubResource("BTPlayAnimation_unftu"), SubResource("BTAction_op6l6"), SubResource("BTTimeLimit_gadc6"), SubResource("BTAction_poqpu")]
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_2lneu"]
|
||||
duration = 7.0
|
||||
children = [SubResource("BTSequence_0gdqn")]
|
||||
|
||||
[sub_resource type="BTProbability" id="BTProbability_6sydk"]
|
||||
run_chance = 0.3
|
||||
children = [SubResource("BTCooldown_2lneu")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_kuuw2"]
|
||||
script = ExtResource("4_53hao")
|
||||
target_var = &"target"
|
||||
flank_side = 0
|
||||
range_min = 400
|
||||
range_max = 1000
|
||||
position_var = &"shoot_pos"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_kc64r"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_panch"]
|
||||
animation_player = SubResource("BBNode_kc64r")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_66hsk"]
|
||||
script = ExtResource("3_q4r2p")
|
||||
target_position_var = &"shoot_pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_24ath"]
|
||||
children = [SubResource("BTAction_66hsk")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_enw2m"]
|
||||
script = ExtResource("5_aexyq")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_1fnyc"]
|
||||
script = ExtResource("2_a8qex")
|
||||
target_var = &"target"
|
||||
tolerance = 150.0
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_s6vt4"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qa8jy"]
|
||||
animation_player = SubResource("BBNode_s6vt4")
|
||||
animation_name = &"throw_prepare"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_gbcyb"]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_qkfqt"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_0ktds"]
|
||||
await_completion = 1.0
|
||||
animation_player = SubResource("BBNode_qkfqt")
|
||||
animation_name = &"throw"
|
||||
blend = 0.05
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_1yxc5"]
|
||||
saved_value = NodePath(".")
|
||||
resource_name = "."
|
||||
|
||||
[sub_resource type="BTCallMethod" id="BTCallMethod_yx4fk"]
|
||||
node = SubResource("BBNode_1yxc5")
|
||||
method = &"throw_ninja_star"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_d2ib4"]
|
||||
duration = 0.2
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_rgbq3"]
|
||||
custom_name = "Throw ninja star"
|
||||
children = [SubResource("BTPlayAnimation_qa8jy"), SubResource("BTWait_gbcyb"), SubResource("BTPlayAnimation_0ktds"), SubResource("BTCallMethod_yx4fk"), SubResource("BTWait_d2ib4")]
|
||||
metadata/_weight_ = 1.0
|
||||
|
||||
[sub_resource type="BTRepeat" id="BTRepeat_g08ia"]
|
||||
times = 3
|
||||
children = [SubResource("BTSequence_rgbq3")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_lhg7f"]
|
||||
custom_name = "Get into position"
|
||||
children = [SubResource("BTAction_kuuw2"), SubResource("BTPlayAnimation_panch"), SubResource("BTTimeLimit_24ath"), SubResource("BTAction_enw2m"), SubResource("BTCondition_1fnyc"), SubResource("BTRepeat_g08ia")]
|
||||
metadata/_weight_ = 1.0
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_1rrya"]
|
||||
children = [SubResource("BTProbability_6sydk"), SubResource("BTSequence_lhg7f")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_pxl2k"]
|
||||
custom_name = "Main"
|
||||
children = [SubResource("BTSequence_yhjh1"), SubResource("BTSelector_1rrya")]
|
||||
|
||||
[resource]
|
||||
description = "Here, the [dec]Probability[/dec] decorator permits the execution of its branch in 30% of cases. This introduces a slight variation to the behavior each time the \"Change flank\" sequence is considered by the [comp]Selector[/comp].
|
||||
|
||||
The [dec]Repeat[/dec] decorator is handy for doing something multiple times within a behavior tree. In our example, it's used to make the [comp]Throw ninja star[/comp] sequence perform three times in a row."
|
||||
blackboard_plan = SubResource("BlackboardPlan_46tbn")
|
||||
root_task = SubResource("BTSequence_pxl2k")
|
||||
163
demo/ai/trees/06_agent_melee_combo.tres
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=39 format=3 uid="uid://cpncl1db8j12f"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_sf4l8"]
|
||||
[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/move_forward.gd" id="5_au5yc"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"]
|
||||
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 = ""
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_nrd4b"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
|
||||
animation_player = SubResource("BBNode_nrd4b")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"]
|
||||
min_duration = 0.7
|
||||
max_duration = 1.5
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ulbrf"]
|
||||
script = ExtResource("1_sf4l8")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_yhjh1"]
|
||||
custom_name = "Pause before action"
|
||||
children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8"), SubResource("BTAction_ulbrf")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_85keo"]
|
||||
script = ExtResource("2_5nwkp")
|
||||
target_var = &"target"
|
||||
flank_side = 0
|
||||
range_min = 300
|
||||
range_max = 400
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_wpj6d"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"]
|
||||
animation_player = SubResource("BBNode_wpj6d")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ygjnc"]
|
||||
script = ExtResource("3_3tom2")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"]
|
||||
children = [SubResource("BTAction_ygjnc")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_1xfnq"]
|
||||
custom_name = "Align with player"
|
||||
children = [SubResource("BTAction_85keo"), SubResource("BTPlayAnimation_olf37"), SubResource("BTTimeLimit_xek5v")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_kidxn"]
|
||||
script = ExtResource("4_hi228")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_giv5l"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_usdja"]
|
||||
animation_player = SubResource("BBNode_giv5l")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_tadkc"]
|
||||
duration = 0.4
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_s8evu"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_s8evu")
|
||||
animation_name = &"attack_1"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_u22bc"]
|
||||
script = ExtResource("5_au5yc")
|
||||
speed_var = &"charge_speed"
|
||||
duration = 0.1
|
||||
|
||||
[sub_resource type="BTParallel" id="BTParallel_ec2e3"]
|
||||
num_successes_required = 2
|
||||
children = [SubResource("BTPlayAnimation_ppmxd"), SubResource("BTAction_u22bc")]
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_c0lo0"]
|
||||
duration = 0.2
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_3oljv"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_q4uis"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_3oljv")
|
||||
animation_name = &"attack_2"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_yuxl3"]
|
||||
script = ExtResource("5_au5yc")
|
||||
speed_var = &"charge_speed"
|
||||
duration = 0.1
|
||||
|
||||
[sub_resource type="BTParallel" id="BTParallel_thojy"]
|
||||
num_successes_required = 2
|
||||
children = [SubResource("BTPlayAnimation_q4uis"), SubResource("BTAction_yuxl3")]
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_y3pmv"]
|
||||
duration = 0.2
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_ot40l"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ye5pt"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_ot40l")
|
||||
animation_name = &"attack_3"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_rwp18"]
|
||||
script = ExtResource("5_au5yc")
|
||||
speed_var = &"charge_speed"
|
||||
duration = 0.1
|
||||
|
||||
[sub_resource type="BTParallel" id="BTParallel_qmdfb"]
|
||||
num_successes_required = 2
|
||||
children = [SubResource("BTPlayAnimation_ye5pt"), SubResource("BTAction_rwp18")]
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_nxyko"]
|
||||
duration = 0.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_ww5v2"]
|
||||
custom_name = "Combo Melee attack"
|
||||
children = [SubResource("BTAction_kidxn"), SubResource("BTPlayAnimation_usdja"), SubResource("BTWait_tadkc"), SubResource("BTParallel_ec2e3"), SubResource("BTWait_c0lo0"), SubResource("BTParallel_thojy"), SubResource("BTWait_y3pmv"), SubResource("BTParallel_qmdfb"), SubResource("BTWait_nxyko")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_pxl2k"]
|
||||
children = [SubResource("BTSequence_yhjh1"), SubResource("BTSequence_1xfnq"), SubResource("BTSequence_ww5v2")]
|
||||
|
||||
[resource]
|
||||
description = "In some scenarios, you might need to execute multiple tasks at the same time until specific conditions are fulfilled. To achieve this, the [comp]Parallel[/comp] composite is an invaluable tool. This composite task allows its children to be executed simultaneously during each tick until a specified number of successes or failures is reached. In this example, it will execute both the [act]PlayAnimation[/act] and [act]MoveForward[/act] actions each tick until both actions have finished with a [SUCCESS] status."
|
||||
blackboard_plan = SubResource("BlackboardPlan_46tbn")
|
||||
root_task = SubResource("BTSequence_pxl2k")
|
||||
219
demo/ai/trees/07_agent_melee_nuanced.tres
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=49 format=3 uid="uid://c2u6sljqkim0n"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_08fik"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_te3yo"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="3_svwk8"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="4_mvsyw"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/pursue.gd" id="5_r1ou0"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"]
|
||||
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/flank_speed/name = &"flank_speed"
|
||||
var/flank_speed/type = 3
|
||||
var/flank_speed/value = 600.0
|
||||
var/flank_speed/hint = 1
|
||||
var/flank_speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_nrd4b"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
|
||||
animation_player = SubResource("BBNode_nrd4b")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"]
|
||||
min_duration = 0.7
|
||||
max_duration = 1.5
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_c4cxo"]
|
||||
script = ExtResource("1_08fik")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_yhjh1"]
|
||||
custom_name = "Pause before action"
|
||||
children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8"), SubResource("BTAction_c4cxo")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_kc64r"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_panch"]
|
||||
animation_player = SubResource("BBNode_kc64r")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
speed = 1.5
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_6e48s"]
|
||||
script = ExtResource("2_te3yo")
|
||||
target_var = &"target"
|
||||
flank_side = 1
|
||||
range_min = 400
|
||||
range_max = 600
|
||||
position_var = &"flank_pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_66hsk"]
|
||||
script = ExtResource("3_svwk8")
|
||||
target_position_var = &"flank_pos"
|
||||
speed_var = &"flank_speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &"target"
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_24ath"]
|
||||
children = [SubResource("BTAction_66hsk")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_enw2m"]
|
||||
script = ExtResource("4_mvsyw")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_lhg7f"]
|
||||
custom_name = "Flank player"
|
||||
children = [SubResource("BTPlayAnimation_panch"), SubResource("BTAction_6e48s"), SubResource("BTTimeLimit_24ath"), SubResource("BTAction_enw2m")]
|
||||
metadata/_weight_ = 1.0
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_skw41"]
|
||||
duration = 6.0
|
||||
children = [SubResource("BTSequence_lhg7f")]
|
||||
metadata/_weight_ = 2.0
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_wpj6d"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"]
|
||||
animation_player = SubResource("BBNode_wpj6d")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_a4jqi"]
|
||||
script = ExtResource("5_r1ou0")
|
||||
target_var = &"target"
|
||||
speed_var = &"speed"
|
||||
approach_distance = 100.0
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"]
|
||||
time_limit = 2.0
|
||||
children = [SubResource("BTAction_a4jqi")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_kidxn"]
|
||||
script = ExtResource("4_mvsyw")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_tadkc"]
|
||||
duration = 0.1
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_g8qww"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_a8yqu"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_g8qww")
|
||||
animation_name = &"attack_2"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_vjstl"]
|
||||
duration = 0.1
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_rfop0"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_8oyw6"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_rfop0")
|
||||
animation_name = &"attack_3"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_1xfnq"]
|
||||
custom_name = "Approach and melee attack"
|
||||
children = [SubResource("BTPlayAnimation_olf37"), SubResource("BTTimeLimit_xek5v"), SubResource("BTAction_kidxn"), SubResource("BTWait_tadkc"), SubResource("BTPlayAnimation_a8yqu"), SubResource("BTWait_vjstl"), SubResource("BTPlayAnimation_8oyw6")]
|
||||
metadata/_weight_ = 4.0
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_mf87t"]
|
||||
script = ExtResource("2_te3yo")
|
||||
target_var = &"target"
|
||||
flank_side = 0
|
||||
range_min = 350
|
||||
range_max = 600
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_cx111"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_mfbeu"]
|
||||
animation_player = SubResource("BBNode_cx111")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_6nx58"]
|
||||
script = ExtResource("3_svwk8")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_tidwl"]
|
||||
time_limit = 3.0
|
||||
children = [SubResource("BTAction_6nx58")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_8q20y"]
|
||||
script = ExtResource("4_mvsyw")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_s6vt4"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qa8jy"]
|
||||
animation_player = SubResource("BBNode_s6vt4")
|
||||
animation_name = &"throw_prepare"
|
||||
blend = 0.1
|
||||
speed = 0.7
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_gbcyb"]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_qkfqt"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_0ktds"]
|
||||
await_completion = 1.0
|
||||
animation_player = SubResource("BBNode_qkfqt")
|
||||
animation_name = &"throw"
|
||||
blend = 0.05
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_1yxc5"]
|
||||
saved_value = NodePath(".")
|
||||
resource_name = "."
|
||||
|
||||
[sub_resource type="BTCallMethod" id="BTCallMethod_yx4fk"]
|
||||
node = SubResource("BBNode_1yxc5")
|
||||
method = &"throw_ninja_star"
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_2pmoe"]
|
||||
max_duration = 1.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_rgbq3"]
|
||||
custom_name = "Throw ninja star"
|
||||
children = [SubResource("BTAction_mf87t"), SubResource("BTPlayAnimation_mfbeu"), SubResource("BTTimeLimit_tidwl"), SubResource("BTAction_8q20y"), SubResource("BTPlayAnimation_qa8jy"), SubResource("BTWait_gbcyb"), SubResource("BTPlayAnimation_0ktds"), SubResource("BTCallMethod_yx4fk"), SubResource("BTRandomWait_2pmoe")]
|
||||
metadata/_weight_ = 2.0
|
||||
|
||||
[sub_resource type="BTProbabilitySelector" id="BTProbabilitySelector_rjsiq"]
|
||||
abort_on_failure = true
|
||||
children = [SubResource("BTCooldown_skw41"), SubResource("BTSequence_1xfnq"), SubResource("BTSequence_rgbq3")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_pxl2k"]
|
||||
custom_name = "Main"
|
||||
children = [SubResource("BTSequence_yhjh1"), SubResource("BTProbabilitySelector_rjsiq")]
|
||||
|
||||
[resource]
|
||||
description = "[comp]ProbabilitySelector[/comp] chooses a child task to execute based on attached probabilities. Probability distribution is calculated based on weights assigned to each child task.
|
||||
"
|
||||
blackboard_plan = SubResource("BlackboardPlan_46tbn")
|
||||
root_task = SubResource("BTSequence_pxl2k")
|
||||
200
demo/ai/trees/08_agent_demon.tres
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=49 format=3 uid="uid://cpcnbi81jqge4"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_ce4la"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/in_range.gd" id="2_atyuj"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="3_3mw7l"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/back_away.gd" id="4_6dr32"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="5_dho0d"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="6_0pfsl"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_8ay3j"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_lpri5"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_p3e7a"]
|
||||
animation_player = SubResource("BBNode_lpri5")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_j6cjm"]
|
||||
min_duration = 2.0
|
||||
max_duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_5thv4"]
|
||||
custom_name = "Chill"
|
||||
children = [SubResource("BTPlayAnimation_p3e7a"), SubResource("BTRandomWait_j6cjm")]
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_oms7a"]
|
||||
trigger_on_failure = true
|
||||
children = [SubResource("BTSequence_5thv4")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ohfp7"]
|
||||
script = ExtResource("1_ce4la")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_7a5nv"]
|
||||
script = ExtResource("2_atyuj")
|
||||
distance_min = 0.0
|
||||
distance_max = 150.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ddvrs"]
|
||||
script = ExtResource("3_3mw7l")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_c4nfu"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_yytkn"]
|
||||
await_completion = 3.0
|
||||
animation_player = SubResource("BBNode_c4nfu")
|
||||
animation_name = &"attack_3"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_ejg6q"]
|
||||
duration = 3.0
|
||||
children = [SubResource("BTPlayAnimation_yytkn")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_eikr4"]
|
||||
custom_name = "Melee"
|
||||
children = [SubResource("BTAction_ohfp7"), SubResource("BTCondition_7a5nv"), SubResource("BTAction_ddvrs"), SubResource("BTCooldown_ejg6q")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_h75v8"]
|
||||
script = ExtResource("2_atyuj")
|
||||
distance_min = 0.0
|
||||
distance_max = 300.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_wpt7j"]
|
||||
script = ExtResource("3_3mw7l")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_iv62h"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wnaul"]
|
||||
animation_player = SubResource("BBNode_iv62h")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
speed = -1.0
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_h2efl"]
|
||||
script = ExtResource("4_6dr32")
|
||||
speed_var = &"speed"
|
||||
max_angle_deviation = 0.7
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_wm5g2"]
|
||||
time_limit = 1.0
|
||||
children = [SubResource("BTAction_h2efl")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_wh4dl"]
|
||||
custom_name = "Back away"
|
||||
children = [SubResource("BTCondition_h75v8"), SubResource("BTAction_wpt7j"), SubResource("BTPlayAnimation_wnaul"), SubResource("BTTimeLimit_wm5g2")]
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_mqte5"]
|
||||
custom_name = "Get into position"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_edmui"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_vjtpq"]
|
||||
animation_player = SubResource("BBNode_edmui")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_4mmh0"]
|
||||
script = ExtResource("5_dho0d")
|
||||
target_var = &"target"
|
||||
flank_side = 0
|
||||
range_min = 300
|
||||
range_max = 700
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_vb5c3"]
|
||||
script = ExtResource("6_0pfsl")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_jyks2"]
|
||||
children = [SubResource("BTAction_vb5c3")]
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_ym6nj"]
|
||||
custom_name = "Short break before action"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_fkevy"]
|
||||
script = ExtResource("3_3mw7l")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_lh25u"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_vcjeq"]
|
||||
animation_player = SubResource("BBNode_lh25u")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_42smh"]
|
||||
duration = 0.2
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_nbp2b"]
|
||||
custom_name = "Spit fire!"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_cqw71"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_214yn"]
|
||||
await_completion = 3.0
|
||||
animation_player = SubResource("BBNode_cqw71")
|
||||
animation_name = &"spit"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_dv5b5"]
|
||||
saved_value = NodePath(".")
|
||||
resource_name = "."
|
||||
|
||||
[sub_resource type="BTCallMethod" id="BTCallMethod_lk7i6"]
|
||||
node = SubResource("BBNode_dv5b5")
|
||||
method = &"spit_fire"
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_fndxk"]
|
||||
custom_name = "Wind down"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_m68ui"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_m7gyp"]
|
||||
animation_player = SubResource("BBNode_m68ui")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_v0el8"]
|
||||
min_duration = 0.7
|
||||
max_duration = 1.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_djtph"]
|
||||
custom_name = "Spit fire"
|
||||
children = [SubResource("BTComment_mqte5"), SubResource("BTPlayAnimation_vjtpq"), SubResource("BTAction_4mmh0"), SubResource("BTTimeLimit_jyks2"), SubResource("BTComment_ym6nj"), SubResource("BTAction_fkevy"), SubResource("BTPlayAnimation_vcjeq"), SubResource("BTWait_42smh"), SubResource("BTComment_nbp2b"), SubResource("BTPlayAnimation_214yn"), SubResource("BTCallMethod_lk7i6"), SubResource("BTComment_fndxk"), SubResource("BTPlayAnimation_m7gyp"), SubResource("BTRandomWait_v0el8")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_feba6"]
|
||||
children = [SubResource("BTCooldown_oms7a"), SubResource("BTSequence_eikr4"), SubResource("BTSequence_wh4dl"), SubResource("BTSequence_djtph")]
|
||||
|
||||
[resource]
|
||||
description = "Here, we use the [con]InRange[/con] condition task together with [comp]Sequence[/comp] and [comp]Selector[/comp] to create a reactive behavior for this agent. When the player comes close, this agent will attempt to hit them with a melee attack and move away afterward for a better ranged position."
|
||||
blackboard_plan = SubResource("BlackboardPlan_8ay3j")
|
||||
root_task = SubResource("BTSelector_feba6")
|
||||
155
demo/ai/trees/09_agent_summoner.tres
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=35 format=3 uid="uid://cpxk7jnqpwwlc"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_sgn0p"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="2_pshl2"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_58oq1"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 300.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
var/summon_cooldown/name = &"summon_cooldown"
|
||||
var/summon_cooldown/type = 1
|
||||
var/summon_cooldown/value = false
|
||||
var/summon_cooldown/hint = 0
|
||||
var/summon_cooldown/hint_string = ""
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_b7euf"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_sot6a"]
|
||||
animation_player = SubResource("BBNode_b7euf")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_0wc6p"]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_kwkxc"]
|
||||
custom_name = "Summoning sickness"
|
||||
children = [SubResource("BTPlayAnimation_sot6a"), SubResource("BTRandomWait_0wc6p")]
|
||||
|
||||
[sub_resource type="BTRunLimit" id="BTRunLimit_x2jr4"]
|
||||
children = [SubResource("BTSequence_kwkxc")]
|
||||
|
||||
[sub_resource type="BBVariant" id="BBVariant_y3x7n"]
|
||||
type = 2
|
||||
saved_value = 6
|
||||
resource_name = "6"
|
||||
|
||||
[sub_resource type="BTCheckAgentProperty" id="BTCheckAgentProperty_olmdj"]
|
||||
property = &"summon_count"
|
||||
check_type = 1
|
||||
value = SubResource("BBVariant_y3x7n")
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_ef6y0"]
|
||||
custom_name = "Variable $summon_cooldown is updated by the Cooldown task below"
|
||||
|
||||
[sub_resource type="BBVariant" id="BBVariant_hgde2"]
|
||||
type = 1
|
||||
saved_value = false
|
||||
resource_name = "false"
|
||||
|
||||
[sub_resource type="BTCheckVar" id="BTCheckVar_hc3o3"]
|
||||
variable = &"summon_cooldown"
|
||||
value = SubResource("BBVariant_hgde2")
|
||||
children = [SubResource("BTComment_ef6y0")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_q8bei"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_6leni"]
|
||||
animation_player = SubResource("BBNode_q8bei")
|
||||
animation_name = &"summon"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_8og18"]
|
||||
duration = 0.5
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_yeyns"]
|
||||
script = ExtResource("1_sgn0p")
|
||||
range_min = 300.0
|
||||
range_max = 500.0
|
||||
position_var = &"minion_pos"
|
||||
|
||||
[sub_resource type="BBVariant" id="BBVariant_wfjwy"]
|
||||
type = 5
|
||||
value_source = 1
|
||||
variable = &"minion_pos"
|
||||
resource_name = "$minion_pos"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_v271m"]
|
||||
saved_value = NodePath(".")
|
||||
resource_name = "."
|
||||
|
||||
[sub_resource type="BTCallMethod" id="BTCallMethod_4ath5"]
|
||||
node = SubResource("BBNode_v271m")
|
||||
method = &"summon_minion"
|
||||
args = Array[BBVariant]([SubResource("BBVariant_wfjwy")])
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_25f70"]
|
||||
duration = 6.0
|
||||
cooldown_state_var = &"summon_cooldown"
|
||||
children = [SubResource("BTCallMethod_4ath5")]
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_tdhfn"]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_2n742"]
|
||||
custom_name = "Summon minion"
|
||||
children = [SubResource("BTCheckAgentProperty_olmdj"), SubResource("BTCheckVar_hc3o3"), SubResource("BTPlayAnimation_6leni"), SubResource("BTWait_8og18"), SubResource("BTAction_yeyns"), SubResource("BTCooldown_25f70"), SubResource("BTWait_tdhfn")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_33wje"]
|
||||
script = ExtResource("1_sgn0p")
|
||||
range_min = 300.0
|
||||
range_max = 700.0
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_w5fh2"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qbxm8"]
|
||||
animation_player = SubResource("BBNode_w5fh2")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_dfifw"]
|
||||
script = ExtResource("2_pshl2")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_i05cm"]
|
||||
time_limit = 3.0
|
||||
children = [SubResource("BTAction_dfifw")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_vinxt"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_t7drr"]
|
||||
animation_player = SubResource("BBNode_vinxt")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_axjfh"]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_ks71q"]
|
||||
custom_name = "Chill"
|
||||
children = [SubResource("BTPlayAnimation_t7drr"), SubResource("BTRandomWait_axjfh")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_dss4d"]
|
||||
custom_name = "Reposition"
|
||||
children = [SubResource("BTAction_33wje"), SubResource("BTPlayAnimation_qbxm8"), SubResource("BTTimeLimit_i05cm"), SubResource("BTSequence_ks71q")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_gp6q5"]
|
||||
children = [SubResource("BTRunLimit_x2jr4"), SubResource("BTSequence_2n742"), SubResource("BTSequence_dss4d")]
|
||||
|
||||
[resource]
|
||||
description = "[con]CheckAgentProperty[/con] examines the agent’s property value and compares it to a given value or a blackboard variable. In this example, it checks if the [color=cyan]summon_count[/color] property is less than 6.
|
||||
You can also check or share a [dec]Cooldown[/dec] in different parts of the behavior tree if you provide a blackboard variable for the [dec]Cooldown[/dec] decorator to use. [con]CheckVar[/con] is responsible here for examining the cooldown variable named \"summon_cooldown\"."
|
||||
blackboard_plan = SubResource("BlackboardPlan_58oq1")
|
||||
root_task = SubResource("BTSelector_gp6q5")
|
||||
29
demo/ai/trees/tutorial/tutorial_01_welcome.tres
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=5 format=3 uid="uid://b1mfh8yad7rmw"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_fq0jf"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_rsejo"]
|
||||
animation_player = SubResource("BBNode_fq0jf")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_4bq32"]
|
||||
children = [SubResource("BTPlayAnimation_rsejo")]
|
||||
|
||||
[resource]
|
||||
description = "Welcome to the [b]LimboAI Tutorial[/b]!
|
||||
|
||||
Here, you'll learn how to use behavior trees to craft AI for your games. We'll start with the basics and gradually move to more advanced topics. Strap in for a quick and engaging introduction to behavior trees.
|
||||
|
||||
Press ➡ button in the top-right corner to proceed.
|
||||
Press ⬅ button any time you want to go back to a previous chapter."
|
||||
blackboard_plan = SubResource("BlackboardPlan_ewfwq")
|
||||
root_task = SubResource("BTSequence_4bq32")
|
||||
45
demo/ai/trees/tutorial/tutorial_02_introduction.tres
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=9 format=3 uid="uid://b1i0xo0o676va"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"]
|
||||
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/flank_speed/name = &"flank_speed"
|
||||
var/flank_speed/type = 3
|
||||
var/flank_speed/value = 600.0
|
||||
var/flank_speed/hint = 1
|
||||
var/flank_speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_wu06u"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_dubaq"]
|
||||
animation_player = SubResource("BBNode_wu06u")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_meli1"]
|
||||
duration = 5.0
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_mgehh"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_0fqno"]
|
||||
animation_player = SubResource("BBNode_mgehh")
|
||||
animation_name = &"dance"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_m3h4o"]
|
||||
duration = 5.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_rbfdh"]
|
||||
children = [SubResource("BTPlayAnimation_dubaq"), SubResource("BTWait_meli1"), SubResource("BTPlayAnimation_0fqno"), SubResource("BTWait_m3h4o")]
|
||||
|
||||
[resource]
|
||||
description = "Behavior trees are designed to simplify the creation of responsive and modular behaviors for games. They consist of tasks that represent specific actions or decision-making rules. Tasks can be broadly categorized into two groups: control tasks and leaf tasks. [b]Control tasks[/b] dictate the execution flow within the tree, while [b]leaf tasks[/b] represent specific actions to perform (such as moving or attacking) or conditions that need to be checked. Typically, it's the leaf tasks that perform the actual work in behavior trees.
|
||||
|
||||
A behavior tree is usually processed each frame (physics frame by default). It is traversed from top to bottom, with the control tasks determining the control flow. Each task has a [color=cyan]_tick[/color] method, which performs the task's work and returns a status indicating its progress: [SUCCESS], [FAILURE], or [RUNNING]. [SUCCESS] and [FAILURE] indicate the outcome of finished work, while [RUNNING] status is returned when a task requires more than one tick to complete its job. These statuses determine how the tree progresses, with the [RUNNING] status usually meaning that the tree will continue execution during the next frame."
|
||||
blackboard_plan = SubResource("BlackboardPlan_ewfwq")
|
||||
root_task = SubResource("BTSequence_rbfdh")
|
||||
97
demo/ai/trees/tutorial/tutorial_03_types.tres
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=24 format=3 uid="uid://cb0ybf24ahnc3"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_as4cg"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="2_dlpnp"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="3_uv18s"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/in_range.gd" id="4_k3g8t"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="5_thvy5"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_20ku0"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_57u80"]
|
||||
animation_player = SubResource("BBNode_20ku0")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_11xvc"]
|
||||
script = ExtResource("1_as4cg")
|
||||
range_min = 300.0
|
||||
range_max = 500.0
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_tdkpj"]
|
||||
script = ExtResource("2_dlpnp")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_echit"]
|
||||
children = [SubResource("BTPlayAnimation_57u80"), SubResource("BTAction_11xvc"), SubResource("BTAction_tdkpj")]
|
||||
|
||||
[sub_resource type="BTProbability" id="BTProbability_g0ol3"]
|
||||
children = [SubResource("BTSequence_echit")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_124bm"]
|
||||
script = ExtResource("3_uv18s")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_n25o8"]
|
||||
script = ExtResource("4_k3g8t")
|
||||
distance_min = 0.0
|
||||
distance_max = 200.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_1hfgr"]
|
||||
script = ExtResource("5_thvy5")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_ilr2h"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_mrsu3"]
|
||||
animation_player = SubResource("BBNode_ilr2h")
|
||||
animation_name = &"attack_1"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_5vug3"]
|
||||
children = [SubResource("BTAction_124bm"), SubResource("BTCondition_n25o8"), SubResource("BTAction_1hfgr"), SubResource("BTPlayAnimation_mrsu3")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_fq0jf"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_rsejo"]
|
||||
animation_player = SubResource("BBNode_fq0jf")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_dl31p"]
|
||||
duration = 2.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_vx4uy"]
|
||||
children = [SubResource("BTPlayAnimation_rsejo"), SubResource("BTWait_dl31p")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_tdpek"]
|
||||
children = [SubResource("BTProbability_g0ol3"), SubResource("BTSequence_5vug3"), SubResource("BTSequence_vx4uy")]
|
||||
|
||||
[resource]
|
||||
description = "There are four types of tasks:
|
||||
[ul][act]Actions[/act] are leaf tasks that perform the actual work.[/ul]
|
||||
[ul][con]Conditions[/con] are leaf tasks that conduct various checks.[/ul]
|
||||
[ul][comp]Composites[/comp] can have one or more child tasks, and dictate the execution flow of their children.[/ul]
|
||||
[ul][dec]Decorators[/dec] can only have a single child and they change how their child task operates.[/ul]
|
||||
|
||||
Let's take a look into actions first. [act]Actions[/act] are responsible for most of the work and often change the game state in a significant manner. For instance, [act]PlayAnimation[/act] instructs the AnimationPlayer to start a specified animation, with the option to wait for its completion. On the other hand, the [act]Wait[/act] task simply pauses for a set duration before returning [SUCCESS].
|
||||
|
||||
Next, we'll explore the core composite tasks, such as [comp]Sequence[/comp] and [comp]Selector[/comp]. These are among the most crucial composites that you should know about."
|
||||
blackboard_plan = SubResource("BlackboardPlan_ewfwq")
|
||||
root_task = SubResource("BTSelector_tdpek")
|
||||
62
demo/ai/trees/tutorial/tutorial_04_sequence.tres
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=15 format=3 uid="uid://dln8ywvtqedt7"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_gk66j"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="2_v5eou"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_fq0jf"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_rsejo"]
|
||||
animation_player = SubResource("BBNode_fq0jf")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_dl31p"]
|
||||
duration = 3.0
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_6d0yy"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"]
|
||||
animation_player = SubResource("BBNode_6d0yy")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_fc1oo"]
|
||||
script = ExtResource("1_gk66j")
|
||||
range_min = 300.0
|
||||
range_max = 500.0
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_djl5v"]
|
||||
script = ExtResource("2_v5eou")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTFail" id="BTFail_i2f36"]
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_4i06i"]
|
||||
custom_name = "👇️ Sequence is never going to reach this task, because it fails at the previous step."
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_yxpnx"]
|
||||
duration = 888.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_vx4uy"]
|
||||
children = [SubResource("BTPlayAnimation_rsejo"), SubResource("BTWait_dl31p"), SubResource("BTPlayAnimation_wsspf"), SubResource("BTAction_fc1oo"), SubResource("BTAction_djl5v"), SubResource("BTFail_i2f36"), SubResource("BTComment_4i06i"), SubResource("BTWait_yxpnx")]
|
||||
|
||||
[resource]
|
||||
description = "The [comp]Sequence[/comp] is one of the core composite tasks. It executes its child tasks sequentially, from first to last, until one of them returns [FAILURE], or all of them result in [SUCCESS]. In other words, if any child task results in [FAILURE], the Sequence execution will be aborted, and the Sequence itself will return [FAILURE].
|
||||
|
||||
In our example, you can observe a simple [comp]Sequence[/comp] in action. Notice how it fails when it reaches the [act]Fail[/act] action and never proceeds to the [act]Wait 888 sec[/act] action afterward. By the way, the simple [act]Fail[/act] task is quite useful for troubleshooting. Its sole function is to return [FAILURE].
|
||||
"
|
||||
blackboard_plan = SubResource("BlackboardPlan_ewfwq")
|
||||
root_task = SubResource("BTSequence_vx4uy")
|
||||
108
demo/ai/trees/tutorial/tutorial_05_selector.tres
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=26 format=3 uid="uid://bf4r652fv5kwi"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_3ed74"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_rvh1c"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/in_range.gd" id="2_jfsyt"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/pursue.gd" id="2_nnswb"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="2_t62a0"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_x0uu7"]
|
||||
script = ExtResource("2_jfsyt")
|
||||
distance_min = 0.0
|
||||
distance_max = 200.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_icf24"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_iiei3"]
|
||||
animation_player = SubResource("BBNode_icf24")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_824oc"]
|
||||
script = ExtResource("1_rvh1c")
|
||||
range_min = 700.0
|
||||
range_max = 800.0
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_y1you"]
|
||||
script = ExtResource("2_t62a0")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_ayt56"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_l1tdg"]
|
||||
animation_player = SubResource("BBNode_ayt56")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_hh8ys"]
|
||||
duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_cgwor"]
|
||||
children = [SubResource("BTCondition_x0uu7"), SubResource("BTPlayAnimation_iiei3"), SubResource("BTAction_824oc"), SubResource("BTAction_y1you"), SubResource("BTPlayAnimation_l1tdg"), SubResource("BTWait_hh8ys")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_d6aub"]
|
||||
script = ExtResource("2_jfsyt")
|
||||
distance_min = 200.0
|
||||
distance_max = 10000.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_6d0yy"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"]
|
||||
animation_player = SubResource("BBNode_6d0yy")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_wc11r"]
|
||||
script = ExtResource("2_nnswb")
|
||||
target_var = &"target"
|
||||
speed_var = &"speed"
|
||||
approach_distance = 100.0
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_aw5jj"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_3aihc"]
|
||||
animation_player = SubResource("BBNode_aw5jj")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_1o163"]
|
||||
duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_vx4uy"]
|
||||
children = [SubResource("BTCondition_d6aub"), SubResource("BTPlayAnimation_wsspf"), SubResource("BTAction_wc11r"), SubResource("BTPlayAnimation_3aihc"), SubResource("BTWait_1o163")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_2murg"]
|
||||
script = ExtResource("1_3ed74")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_ddhoo"]
|
||||
children = [SubResource("BTSequence_cgwor"), SubResource("BTSequence_vx4uy"), SubResource("BTAction_2murg")]
|
||||
|
||||
[resource]
|
||||
description = "The [comp]Selector[/comp] is another essential composite task. It executes its child tasks sequentially, from first to last, until one of them returns [SUCCESS] or all of them result in [FAILURE]. In other words, when a child task results in [FAILURE], it moves on to the next one until it finds the one that returns [SUCCESS]. Once a child task results in [SUCCESS], the Selector stops and also returns [SUCCESS].
|
||||
|
||||
To understand the [comp]Selector[/comp], it helps to see it as the opposite of the [comp]Sequence[/comp]. While the Sequence continues iterating over children as long as they return [SUCCESS], the Selector does the same but as long as they return [FAILURE]. The purpose of the Selector is to find a child that succeeds. It's often useful to place higher priority tasks at the top so that the Selector attempts them first.
|
||||
|
||||
[comp]Selector[/comp] is frequently used with [comp]Sequence[/comp] and [con]Condition[/con] tasks to control the behavior tree's flow. A condition task would prevent a Sequence from proceeding if it evaluates to [FAILURE], and thus the Selector would try the next child.
|
||||
|
||||
In our example, the [con]InRange[/con] condition checks how far Junior is from the target. When Junior is farther than 200 pixels from the target, he'll attempt to approach it. If he is closer than 200 pixels from the target, he would try to walk away. Thanks to the Selector, only one of these behaviors will be performed at a time, based on the result of the [con]InRange[/con] check. Junior seems to have a dilemma — unable to decide whether to stay or go."
|
||||
blackboard_plan = SubResource("BlackboardPlan_ewfwq")
|
||||
root_task = SubResource("BTSelector_ddhoo")
|
||||
136
demo/ai/trees/tutorial/tutorial_06_decorators.tres
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=34 format=3 uid="uid://beiki511huxb8"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_3xoj7"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/in_range.gd" id="2_08b67"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="3_orhnl"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="4_oyght"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="5_5o1gy"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/pursue.gd" id="6_rpn40"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_2murg"]
|
||||
script = ExtResource("1_3xoj7")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTRunLimit" id="BTRunLimit_60b8b"]
|
||||
children = [SubResource("BTAction_2murg")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_m15aa"]
|
||||
script = ExtResource("2_08b67")
|
||||
distance_min = 0.0
|
||||
distance_max = 200.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_oc76s"]
|
||||
script = ExtResource("3_orhnl")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_6d0yy"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"]
|
||||
await_completion = 5.0
|
||||
animation_player = SubResource("BBNode_6d0yy")
|
||||
animation_name = &"attack_1"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_e0f8v"]
|
||||
children = [SubResource("BTCondition_m15aa"), SubResource("BTAction_oc76s"), SubResource("BTPlayAnimation_wsspf")]
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_3tvjt"]
|
||||
children = [SubResource("BTSequence_e0f8v")]
|
||||
duration = 5.0
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_x0uu7"]
|
||||
script = ExtResource("2_08b67")
|
||||
distance_min = 0.0
|
||||
distance_max = 200.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_icf24"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_iiei3"]
|
||||
animation_player = SubResource("BBNode_icf24")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_824oc"]
|
||||
script = ExtResource("4_oyght")
|
||||
range_min = 700.0
|
||||
range_max = 800.0
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_y1you"]
|
||||
script = ExtResource("5_5o1gy")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_ayt56"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_l1tdg"]
|
||||
animation_player = SubResource("BBNode_ayt56")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_hh8ys"]
|
||||
duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_cgwor"]
|
||||
children = [SubResource("BTCondition_x0uu7"), SubResource("BTPlayAnimation_iiei3"), SubResource("BTAction_824oc"), SubResource("BTAction_y1you"), SubResource("BTPlayAnimation_l1tdg"), SubResource("BTWait_hh8ys")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_d6aub"]
|
||||
script = ExtResource("2_08b67")
|
||||
distance_min = 200.0
|
||||
distance_max = 10000.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_rpwld"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_dug2k"]
|
||||
animation_player = SubResource("BBNode_rpwld")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_wc11r"]
|
||||
script = ExtResource("6_rpn40")
|
||||
target_var = &"target"
|
||||
speed_var = &"speed"
|
||||
approach_distance = 100.0
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_aw5jj"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_3aihc"]
|
||||
animation_player = SubResource("BBNode_aw5jj")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_1o163"]
|
||||
duration = 0.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_vx4uy"]
|
||||
children = [SubResource("BTCondition_d6aub"), SubResource("BTPlayAnimation_dug2k"), SubResource("BTAction_wc11r"), SubResource("BTPlayAnimation_3aihc"), SubResource("BTWait_1o163")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_ddhoo"]
|
||||
children = [SubResource("BTRunLimit_60b8b"), SubResource("BTCooldown_3tvjt"), SubResource("BTSequence_cgwor"), SubResource("BTSequence_vx4uy")]
|
||||
|
||||
[resource]
|
||||
description = "Let's improve our previous behavior, and take the opportunity to discuss [dec]Decorators[/dec]. As mentioned earlier, decorators are control tasks that should only have a single child. Typically, a decorator either alters how its child operates or modifies its return status. They are often a useful tool for introducing variance into behaviors that otherwise lack it.
|
||||
|
||||
In our example, we utilize the [dec]RunLimit[/dec] decorator to restrict its child from running more than once. After executing the first time, the child will never receive another tick. This is quite handy for all sorts of setup logic!
|
||||
|
||||
Now, let's examine another decorator we use here - the [dec]Cooldown[/dec]. This decorator executes its child task only if the specified duration time has passed since the previous execution of the child task. The first time the attack sequence results in [SUCCESS], it triggers the cooldown, preventing the [comp]Sequence[/comp] from being executed for the next 5 seconds. During this period, the Cooldown returns [FAILURE] until the specified duration time elapses. It's important to note that it only counts executions that finished with [SUCCESS]. This means that [con]InRange[/con] can be utilized here without triggering the Cooldown!"
|
||||
blackboard_plan = SubResource("BlackboardPlan_ewfwq")
|
||||
root_task = SubResource("BTSelector_ddhoo")
|
||||
143
demo/ai/trees/tutorial/tutorial_07_more_decorators.tres
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=36 format=3 uid="uid://tep50j4d6kgp"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_f605f"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/in_range.gd" id="2_mj1cj"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="3_86p0r"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/back_away.gd" id="4_u0vk1"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/pursue.gd" id="6_1yikm"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_2murg"]
|
||||
script = ExtResource("1_f605f")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTRunLimit" id="BTRunLimit_60b8b"]
|
||||
children = [SubResource("BTAction_2murg")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_m15aa"]
|
||||
script = ExtResource("2_mj1cj")
|
||||
distance_min = 0.0
|
||||
distance_max = 200.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_oc76s"]
|
||||
script = ExtResource("3_86p0r")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_6d0yy"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"]
|
||||
await_completion = 5.0
|
||||
animation_player = SubResource("BBNode_6d0yy")
|
||||
animation_name = &"attack_1"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_w45kn"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_d2lad"]
|
||||
await_completion = 5.0
|
||||
animation_player = SubResource("BBNode_w45kn")
|
||||
animation_name = &"attack_2"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_e0f8v"]
|
||||
children = [SubResource("BTCondition_m15aa"), SubResource("BTAction_oc76s"), SubResource("BTPlayAnimation_wsspf"), SubResource("BTPlayAnimation_d2lad")]
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_3tvjt"]
|
||||
children = [SubResource("BTSequence_e0f8v")]
|
||||
duration = 5.0
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_x0uu7"]
|
||||
script = ExtResource("2_mj1cj")
|
||||
distance_min = 0.0
|
||||
distance_max = 200.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_wksgd"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_umlwj"]
|
||||
animation_player = SubResource("BBNode_wksgd")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_6q0k4"]
|
||||
script = ExtResource("4_u0vk1")
|
||||
speed_var = &"speed"
|
||||
max_angle_deviation = 0.7
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_6eii7"]
|
||||
children = [SubResource("BTAction_6q0k4")]
|
||||
time_limit = 2.0
|
||||
|
||||
[sub_resource type="BTAlwaysSucceed" id="BTAlwaysSucceed_ieord"]
|
||||
children = [SubResource("BTTimeLimit_6eii7")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_ayt56"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_l1tdg"]
|
||||
animation_player = SubResource("BBNode_ayt56")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_hh8ys"]
|
||||
duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_cgwor"]
|
||||
children = [SubResource("BTCondition_x0uu7"), SubResource("BTPlayAnimation_umlwj"), SubResource("BTAlwaysSucceed_ieord"), SubResource("BTPlayAnimation_l1tdg"), SubResource("BTWait_hh8ys")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_d6aub"]
|
||||
script = ExtResource("2_mj1cj")
|
||||
distance_min = 200.0
|
||||
distance_max = 10000.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_rpwld"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_dug2k"]
|
||||
animation_player = SubResource("BBNode_rpwld")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_wc11r"]
|
||||
script = ExtResource("6_1yikm")
|
||||
target_var = &"target"
|
||||
speed_var = &"speed"
|
||||
approach_distance = 100.0
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_aw5jj"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_3aihc"]
|
||||
animation_player = SubResource("BBNode_aw5jj")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_1o163"]
|
||||
duration = 0.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_vx4uy"]
|
||||
children = [SubResource("BTCondition_d6aub"), SubResource("BTPlayAnimation_dug2k"), SubResource("BTAction_wc11r"), SubResource("BTPlayAnimation_3aihc"), SubResource("BTWait_1o163")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_ddhoo"]
|
||||
children = [SubResource("BTRunLimit_60b8b"), SubResource("BTCooldown_3tvjt"), SubResource("BTSequence_cgwor"), SubResource("BTSequence_vx4uy")]
|
||||
|
||||
[resource]
|
||||
description = "Let's explore some other [dec]Decorators[/dec]. Here's a slightly improved version of the previous behavior. We incorporate the [dec]TimeLimit[/dec] decorator with the [act]Back Away[/act] action to achieve a similar effect as before (walking away from the target). The TimeLimit decorator ensures that the child task does not take too long to finish its work. If the time runs out, the task's execution will be aborted, and TimeLimit will return [FAILURE].
|
||||
|
||||
Another useful decorator is [dec]AlwaysSucceed[/dec], which converts any [FAILURE] returned by its child into [SUCCESS]. We use this decorator here because TimeLimit may result in [FAILURE], but we still want the [comp]Sequence[/comp] to continue. Also, there are similar decorators such as [dec]AlwaysFail[/dec] and [dec]Invert[/dec], which you can use in your behavior trees as needed.
|
||||
|
||||
We also add a second attack, so that Junior feels more badass now. We've got a little hit-and-run behavior going on here!"
|
||||
blackboard_plan = SubResource("BlackboardPlan_ewfwq")
|
||||
root_task = SubResource("BTSelector_ddhoo")
|
||||
204
demo/ai/trees/tutorial/tutorial_08_final_touch.tres
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=52 format=3 uid="uid://dp0cglcytwcj5"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_o5ahw"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_er25a"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="3_ed1xo"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="4_128ei"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/in_range.gd" id="5_er18b"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/back_away.gd" id="6_1urfq"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/pursue.gd" id="7_ekws5"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"]
|
||||
var/speed/name = &"speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_2murg"]
|
||||
script = ExtResource("1_o5ahw")
|
||||
group = &"player"
|
||||
output_var = &"target"
|
||||
|
||||
[sub_resource type="BTRunLimit" id="BTRunLimit_60b8b"]
|
||||
children = [SubResource("BTAction_2murg")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_m15aa"]
|
||||
script = ExtResource("5_er18b")
|
||||
distance_min = 0.0
|
||||
distance_max = 200.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_oc76s"]
|
||||
script = ExtResource("4_128ei")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_6d0yy"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"]
|
||||
await_completion = 5.0
|
||||
animation_player = SubResource("BBNode_6d0yy")
|
||||
animation_name = &"attack_1"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_w45kn"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_d2lad"]
|
||||
await_completion = 5.0
|
||||
animation_player = SubResource("BBNode_w45kn")
|
||||
animation_name = &"attack_2"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_e0f8v"]
|
||||
children = [SubResource("BTCondition_m15aa"), SubResource("BTAction_oc76s"), SubResource("BTPlayAnimation_wsspf"), SubResource("BTPlayAnimation_d2lad")]
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_3tvjt"]
|
||||
children = [SubResource("BTSequence_e0f8v")]
|
||||
duration = 5.0
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_x0uu7"]
|
||||
script = ExtResource("5_er18b")
|
||||
distance_min = 0.0
|
||||
distance_max = 200.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_wksgd"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_umlwj"]
|
||||
animation_player = SubResource("BBNode_wksgd")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_6q0k4"]
|
||||
script = ExtResource("6_1urfq")
|
||||
speed_var = &"speed"
|
||||
max_angle_deviation = 0.7
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_6eii7"]
|
||||
children = [SubResource("BTAction_6q0k4")]
|
||||
time_limit = 2.0
|
||||
|
||||
[sub_resource type="BTAlwaysSucceed" id="BTAlwaysSucceed_ieord"]
|
||||
children = [SubResource("BTTimeLimit_6eii7")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_ayt56"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_l1tdg"]
|
||||
animation_player = SubResource("BBNode_ayt56")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_hh8ys"]
|
||||
duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_cgwor"]
|
||||
children = [SubResource("BTCondition_x0uu7"), SubResource("BTPlayAnimation_umlwj"), SubResource("BTAlwaysSucceed_ieord"), SubResource("BTPlayAnimation_l1tdg"), SubResource("BTWait_hh8ys")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_n0rxm"]
|
||||
script = ExtResource("2_er25a")
|
||||
target_var = &"target"
|
||||
flank_side = 0
|
||||
range_min = 400
|
||||
range_max = 500
|
||||
position_var = &"pos"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_icf24"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_iiei3"]
|
||||
animation_player = SubResource("BBNode_icf24")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_g2up4"]
|
||||
script = ExtResource("3_ed1xo")
|
||||
target_position_var = &"pos"
|
||||
speed_var = &"speed"
|
||||
tolerance = 50.0
|
||||
avoid_var = &""
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_d5lkr"]
|
||||
script = ExtResource("4_128ei")
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_h4k80"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_40yja"]
|
||||
animation_player = SubResource("BBNode_h4k80")
|
||||
animation_name = &"throw_prepare"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_2dc1v"]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_slipn"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qnpjq"]
|
||||
await_completion = 5.0
|
||||
animation_player = SubResource("BBNode_slipn")
|
||||
animation_name = &"throw"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_qaqnn"]
|
||||
resource_name = "."
|
||||
saved_value = NodePath(".")
|
||||
|
||||
[sub_resource type="BTCallMethod" id="BTCallMethod_yd0fn"]
|
||||
node = SubResource("BBNode_qaqnn")
|
||||
method = &"throw_ninja_star"
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_ws7nq"]
|
||||
children = [SubResource("BTAction_n0rxm"), SubResource("BTPlayAnimation_iiei3"), SubResource("BTAction_g2up4"), SubResource("BTAction_d5lkr"), SubResource("BTPlayAnimation_40yja"), SubResource("BTWait_2dc1v"), SubResource("BTPlayAnimation_qnpjq"), SubResource("BTCallMethod_yd0fn")]
|
||||
|
||||
[sub_resource type="BTProbability" id="BTProbability_omklt"]
|
||||
children = [SubResource("BTSequence_ws7nq")]
|
||||
run_chance = 0.25
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_d6aub"]
|
||||
script = ExtResource("5_er18b")
|
||||
distance_min = 200.0
|
||||
distance_max = 10000.0
|
||||
target_var = &"target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_rpwld"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_dug2k"]
|
||||
animation_player = SubResource("BBNode_rpwld")
|
||||
animation_name = &"walk"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_wc11r"]
|
||||
script = ExtResource("7_ekws5")
|
||||
target_var = &"target"
|
||||
speed_var = &"speed"
|
||||
approach_distance = 100.0
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_aw5jj"]
|
||||
resource_name = "AnimationPlayer"
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_3aihc"]
|
||||
animation_player = SubResource("BBNode_aw5jj")
|
||||
animation_name = &"idle"
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_1o163"]
|
||||
duration = 0.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_vx4uy"]
|
||||
children = [SubResource("BTCondition_d6aub"), SubResource("BTPlayAnimation_dug2k"), SubResource("BTAction_wc11r"), SubResource("BTPlayAnimation_3aihc"), SubResource("BTWait_1o163")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_ddhoo"]
|
||||
children = [SubResource("BTRunLimit_60b8b"), SubResource("BTCooldown_3tvjt"), SubResource("BTSequence_cgwor"), SubResource("BTProbability_omklt"), SubResource("BTSequence_vx4uy")]
|
||||
|
||||
[resource]
|
||||
description = "And for the final touch, we've added throwing ninja stars to our previous behavior. The [dec]Probability[/dec] decorator adds a little variance so that we don't throw ninja stars all the time. This decorator executes its child task with a certain probability, so when it's not 100%, sometimes it will return [FAILURE] instead. Some of the work in this [comp]Sequence[/comp] is done by actions you've seen already, and the [act]CallMethod[/act] action invokes the [color=cyan]throw_ninja_star[/color] method on the agent node. By the way, the agent is always the owner of the BTPlayer node, which executes this behavior tree.
|
||||
|
||||
This concludes our tutorial. Hopefully, this little endeavor has been useful to you. You can learn more by reading the [b]Online Documentation[/b], which covers topics like creating your own tasks. Also, check out the [b]Showcase[/b], which presents behaviors of agents made for this little demo. Simply click \"End Tutorial\" to return to the [b]Showcase[/b]."
|
||||
blackboard_plan = SubResource("BlackboardPlan_ewfwq")
|
||||
root_task = SubResource("BTSelector_ddhoo")
|
||||
BIN
demo/assets/agent_bobby.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
34
demo/assets/agent_bobby.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dlo1ine6p5di4"
|
||||
path="res://.godot/imported/agent_bobby.png-8c7c0553d4eefdb06245554fd2603238.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_bobby.png"
|
||||
dest_files=["res://.godot/imported/agent_bobby.png-8c7c0553d4eefdb06245554fd2603238.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_charger.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
34
demo/assets/agent_charger.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ce16nc0wy2s8"
|
||||
path="res://.godot/imported/agent_charger.png-4fbef6fc86342f0b358c84f3e6790641.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_charger.png"
|
||||
dest_files=["res://.godot/imported/agent_charger.png-4fbef6fc86342f0b358c84f3e6790641.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_combo.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
34
demo/assets/agent_combo.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bo0ibp7tvjbba"
|
||||
path="res://.godot/imported/agent_combo.png-1aabf55a6f7673e34d40eadba34cb086.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_combo.png"
|
||||
dest_files=["res://.godot/imported/agent_combo.png-1aabf55a6f7673e34d40eadba34cb086.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_demon.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
34
demo/assets/agent_demon.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d1tx7u8ho0r4v"
|
||||
path="res://.godot/imported/agent_demon.png-8a62722d1d31985ee3a39cfef745c53a.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_demon.png"
|
||||
dest_files=["res://.godot/imported/agent_demon.png-8a62722d1d31985ee3a39cfef745c53a.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_imp.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
34
demo/assets/agent_imp.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://h70okn6hmxum"
|
||||
path="res://.godot/imported/agent_imp.png-9fb23c43583296c91b2a8a01f05daad9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_imp.png"
|
||||
dest_files=["res://.godot/imported/agent_imp.png-9fb23c43583296c91b2a8a01f05daad9.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_junior_pieces.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
34
demo/assets/agent_junior_pieces.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b0oeqsc0xksto"
|
||||
path="res://.godot/imported/agent_junior_pieces.png-95690b27968ceea039daac5098fd3722.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_junior_pieces.png"
|
||||
dest_files=["res://.godot/imported/agent_junior_pieces.png-95690b27968ceea039daac5098fd3722.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_melee_nuanced.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
34
demo/assets/agent_melee_nuanced.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://usu3j55d6dgc"
|
||||
path="res://.godot/imported/agent_melee_nuanced.png-653a64ea55e3175afadb5b209be8b1d0.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_melee_nuanced.png"
|
||||
dest_files=["res://.godot/imported/agent_melee_nuanced.png-653a64ea55e3175afadb5b209be8b1d0.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_melee_simple.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
34
demo/assets/agent_melee_simple.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cw8s50856x8ct"
|
||||
path="res://.godot/imported/agent_melee_simple.png-78a6d279aa99849a5b7788dd5762650f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_melee_simple.png"
|
||||
dest_files=["res://.godot/imported/agent_melee_simple.png-78a6d279aa99849a5b7788dd5762650f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_ranged.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
34
demo/assets/agent_ranged.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cjts4ennjtepg"
|
||||
path="res://.godot/imported/agent_ranged.png-a7be7db55c56f7b1c12ada6338a036cf.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_ranged.png"
|
||||
dest_files=["res://.godot/imported/agent_ranged.png-a7be7db55c56f7b1c12ada6338a036cf.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_skirmisher.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
34
demo/assets/agent_skirmisher.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://l042ovqqsy3l"
|
||||
path="res://.godot/imported/agent_skirmisher.png-fb22c42e0c82e689e3a451b83b1f6ff9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_skirmisher.png"
|
||||
dest_files=["res://.godot/imported/agent_skirmisher.png-fb22c42e0c82e689e3a451b83b1f6ff9.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/agent_summoner.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
34
demo/assets/agent_summoner.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ombnpn2edldt"
|
||||
path="res://.godot/imported/agent_summoner.png-3beb6fd299df05d9586c6b74edd2bbc6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/agent_summoner.png"
|
||||
dest_files=["res://.godot/imported/agent_summoner.png-3beb6fd299df05d9586c6b74edd2bbc6.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/arrow_left.png
Normal file
|
After Width: | Height: | Size: 557 B |
34
demo/assets/arrow_left.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dc1wu244fnetf"
|
||||
path="res://.godot/imported/arrow_left.png-a7d3530ca98c17c281c9ef74dcdcb927.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/arrow_left.png"
|
||||
dest_files=["res://.godot/imported/arrow_left.png-a7d3530ca98c17c281c9ef74dcdcb927.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/arrow_right.png
Normal file
|
After Width: | Height: | Size: 562 B |
34
demo/assets/arrow_right.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bjakugmqbbtw7"
|
||||
path="res://.godot/imported/arrow_right.png-21f7ddc963756a50bd3974181b5e0d02.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/arrow_right.png"
|
||||
dest_files=["res://.godot/imported/arrow_right.png-21f7ddc963756a50bd3974181b5e0d02.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/dummy.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
34
demo/assets/dummy.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cltutcxjx8jnl"
|
||||
path="res://.godot/imported/dummy.png-30069efb95d1cabfca0861ca5010c667.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/dummy.png"
|
||||
dest_files=["res://.godot/imported/dummy.png-30069efb95d1cabfca0861ca5010c667.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/env_clouds.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
34
demo/assets/env_clouds.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://65b6yuobhxf8"
|
||||
path="res://.godot/imported/env_clouds.png-28d790def9247e51c19b24eae86c1a64.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/env_clouds.png"
|
||||
dest_files=["res://.godot/imported/env_clouds.png-28d790def9247e51c19b24eae86c1a64.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/env_gong.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
34
demo/assets/env_gong.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://i476iia1ua8q"
|
||||
path="res://.godot/imported/env_gong.png-22c1657db8aed530e7d811b2b20b4a2d.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/env_gong.png"
|
||||
dest_files=["res://.godot/imported/env_gong.png-22c1657db8aed530e7d811b2b20b4a2d.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/env_ground.png
Normal file
|
After Width: | Height: | Size: 320 KiB |
34
demo/assets/env_ground.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cc7b22sy46gwn"
|
||||
path="res://.godot/imported/env_ground.png-b29c6c47be0779294403cf6615d9dae2.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/env_ground.png"
|
||||
dest_files=["res://.godot/imported/env_ground.png-b29c6c47be0779294403cf6615d9dae2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/env_plants.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
34
demo/assets/env_plants.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://4kw2ks8doc0w"
|
||||
path="res://.godot/imported/env_plants.png-40a908ca223303e0aacba2fca71781c6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/env_plants.png"
|
||||
dest_files=["res://.godot/imported/env_plants.png-40a908ca223303e0aacba2fca71781c6.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/env_rocks.png
Normal file
|
After Width: | Height: | Size: 581 KiB |
34
demo/assets/env_rocks.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b3g14elmg0m36"
|
||||
path="res://.godot/imported/env_rocks.png-12fea7b4727d1ddca76c06fd66910dd0.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/env_rocks.png"
|
||||
dest_files=["res://.godot/imported/env_rocks.png-12fea7b4727d1ddca76c06fd66910dd0.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
demo/assets/fireball.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
34
demo/assets/fireball.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://235liwnxn1n5"
|
||||
path="res://.godot/imported/fireball.png-22a46715cd71373bf765d22c23e664a9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://demo/assets/fireball.png"
|
||||
dest_files=["res://.godot/imported/fireball.png-22a46715cd71373bf765d22c23e664a9.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||