└── addons └── action_behavior_tree ├── lib ├── if.png ├── goto.png ├── link.png ├── queue.png ├── action.png ├── b_node.png ├── monitor.png ├── parallel.png ├── period.png ├── running.png ├── select.png ├── sequence.png ├── switch.png ├── during_select.png ├── running.gd ├── select.gd ├── sequence.gd ├── probable.gd ├── goto.gd ├── link.gd ├── period.gd ├── parallel.gd ├── if.gd ├── switch.gd ├── if.png.import ├── goto.png.import ├── link.png.import ├── queue.png.import ├── action.png.import ├── b_node.png.import ├── period.png.import ├── select.png.import ├── switch.png.import ├── monitor.png.import ├── running.png.import ├── parallel.png.import ├── sequence.png.import ├── during_select.png.import ├── queue.gd ├── during_select.gd ├── group_node.gd ├── b_node.gd ├── action.gd └── monitor.gd ├── demo ├── char.png ├── stick.png ├── hit_state.gd ├── check_hit.gd ├── idle.gd ├── forward.tscn ├── key_down.gd ├── forward.gd ├── scan.gd ├── attack.gd ├── hit.gd ├── char.png.import ├── stick.png.import ├── follow.gd ├── charactor.gd ├── main.tscn ├── char.tscn ├── enemy.tscn └── anim.tscn ├── plugin.cfg ├── LICENSE └── init.gd /addons/action_behavior_tree/lib/if.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/if.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/char.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/demo/char.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/goto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/goto.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/link.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/queue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/queue.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/stick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/demo/stick.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/action.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/b_node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/b_node.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/monitor.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/parallel.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/period.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/period.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/running.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/select.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/sequence.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/switch.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/hit_state.gd: -------------------------------------------------------------------------------- 1 | extends Resource 2 | class_name HitState 3 | 4 | export(float) var power 5 | export(Vector2) var speed 6 | 7 | 8 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/during_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsioteam/action_behavior_tree/HEAD/addons/action_behavior_tree/lib/during_select.png -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/check_hit.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/if.gd" 2 | 3 | 4 | func test(tick): 5 | return tick.target.hit_state != null 6 | 7 | 8 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/idle.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/action.gd" 2 | 3 | func action(tick): 4 | yield(get_tree().create_timer(1), "timeout") 5 | return Status.SUCCEED 6 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="Action Behavior Tree" 4 | description="A behavior tree plugin for action games" 5 | author="gsioteam" 6 | version="0.1.0" 7 | script="init.gd" 8 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/forward.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/action_behavior_tree/demo/forward.gd" type="Script" id=1] 4 | 5 | [node name="Forward" type="Node"] 6 | script = ExtResource( 1 ) 7 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/key_down.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/if.gd" 2 | 3 | export var action: String; 4 | 5 | func test(tick): 6 | return Input.is_action_pressed(action) 7 | 8 | func debug_data(): 9 | return { 10 | "action": action 11 | } 12 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/running.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | 4 | func tick(tick): 5 | for child in get_children(): 6 | if child is BNode: 7 | child.run_tick(tick) 8 | 9 | func reset(): 10 | for child in get_children(): 11 | if child is BNode: 12 | child.reset() 13 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/select.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | 3 | func tick(tick: Tick): 4 | for child in get_children(): 5 | if child is BNode: 6 | var status = child.run_tick(tick); 7 | if status != Status.FAILED: 8 | return status 9 | return Status.FAILED 10 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/sequence.gd: -------------------------------------------------------------------------------- 1 | 2 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 3 | 4 | func tick(tick: Tick): 5 | for child in get_children(): 6 | if child is BNode: 7 | var status = child.run_tick(tick); 8 | if status == Status.FAILED: 9 | return status; 10 | return Status.SUCCEED; 11 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/probable.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/if.gd" 2 | 3 | export var probability: float = 0.2 4 | var last_randon = 0 5 | 6 | func test(tick): 7 | last_randon = randf() 8 | return last_randon < probability 9 | 10 | func debug_data(): 11 | return { 12 | "random": last_randon 13 | } 14 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/goto.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | 3 | export (NodePath) var target_path 4 | var target 5 | 6 | func _ready(): 7 | target = get_node(target_path) 8 | 9 | func tick(tick: Tick): 10 | if target is BNode: 11 | target.require_focus() 12 | return Status.SUCCEED 13 | return Status.SUCCEED 14 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/forward.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/action.gd" 2 | 3 | 4 | export var angle: int = 0 5 | export var speed: float = 50 6 | 7 | func action(tick): 8 | var rad = deg2rad(angle) 9 | tick.target.rotation = rad 10 | var sp = Vector2(0, -speed * Engine.time_scale).rotated(rad); 11 | tick.target.move_and_slide(sp) 12 | return Status.SUCCEED 13 | 14 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/scan.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends "res://addons/action_behavior_tree/lib/if.gd" 3 | 4 | export(NodePath) var scanner 5 | var _scanner 6 | 7 | func get_scanner() -> Area2D: 8 | if _scanner == null: 9 | _scanner = get_node(scanner) 10 | return _scanner 11 | 12 | func test(tick): 13 | var bodis = get_scanner().get_overlapping_bodies() 14 | for body in bodis: 15 | if body.name == "char": 16 | tick.global_context["focus"] = body 17 | return true 18 | return false 19 | 20 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/link.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | # 3 | # The behavior of this node is same as the target node. 4 | export (NodePath) var target_path 5 | 6 | var _target 7 | 8 | func get_target() -> BNode: 9 | if _target == null: 10 | _target = get_node(target_path) 11 | return _target 12 | 13 | func reset(): 14 | .reset() 15 | get_target().reset() 16 | _target = null 17 | 18 | func tick(tick: Tick): 19 | return get_target().run_tick(tick) 20 | 21 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/attack.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/action.gd" 2 | 3 | export var animation: String 4 | var bodis: Array 5 | export(Resource) var hit_state 6 | 7 | func action(tick): 8 | bodis = [] 9 | yield(tick.target.play_anim(animation), "completed") 10 | return Status.SUCCEED 11 | 12 | func can_cancel(tick, frames): 13 | return bodis != null && bodis.size() > 0 14 | 15 | func running(tick, frames): 16 | if hit_state != null: 17 | tick.target.attack(hit_state, bodis) 18 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/period.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | 3 | export var duration: int = 5 4 | var _runningCount: float = 0 5 | var _running = false 6 | 7 | func _init(): 8 | children_count = 1 9 | 10 | func tick(tick: Tick): 11 | if _runningCount > 0: 12 | _runningCount -= Engine.time_scale 13 | find_first().run_tick(tick) 14 | return Status.RUNNING 15 | else: 16 | if _running: 17 | _running = false 18 | find_first().run_tick(tick) 19 | return Status.SUCCEED 20 | else: 21 | _running = true 22 | _runningCount = duration 23 | find_first().run_tick(tick) 24 | return Status.RUNNING 25 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/hit.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/action.gd" 2 | 3 | var speed: Vector2 4 | 5 | func action(tick): 6 | if tick.target.hit_state != null: 7 | var hit_state = tick.target.hit_state 8 | tick.target.hit_state = null 9 | var from = tick.target.hit_from 10 | tick.target.rotation = from.rotation + PI 11 | tick.target.hit_from = null 12 | speed = hit_state.speed 13 | tick.target.get_sprite().modulate = Color(1,0,0,1) 14 | yield(wait(10 * hit_state.power), "completed") 15 | tick.target.get_sprite().modulate = Color(1,1,1,1) 16 | tick.target.speed = Vector2() 17 | return Status.FAILED 18 | 19 | func running(tick, frames): 20 | tick.target.speed = speed * 0.8 21 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/parallel.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | 3 | enum Type { 4 | RUNNING_FIRST, 5 | SUCCED_FIRST, 6 | FAILED_FIRST, 7 | LAST_RESULT 8 | } 9 | 10 | export(Type) var type = Type.RUNNING_FIRST 11 | 12 | func tick(tick: Tick): 13 | var ret = null 14 | for child in get_children(): 15 | if child is BNode: 16 | var result = child.run_tick(tick) 17 | match type: 18 | Type.RUNNING_FIRST: 19 | if ret != Status.RUNNING: 20 | ret = result 21 | Type.SUCCED_FIRST: 22 | if ret != Status.SUCCEED: 23 | ret = result 24 | Type.FAILED_FIRST: 25 | if ret != Status.FAILED: 26 | ret = result 27 | Type.LAST_RESULT: 28 | ret = result 29 | return ret 30 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/if.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | 3 | var running_node = null; 4 | 5 | func _init(): 6 | children_count = 1 7 | 8 | func tick(tick: Tick): 9 | if running_node != null: 10 | var result = running_node.run_tick(tick) 11 | if result != Status.RUNNING: 12 | running_node = null; 13 | return result; 14 | else: 15 | if test(tick): 16 | var child = find_first() 17 | if child != null: 18 | var result = child.run_tick(tick) 19 | if result == Status.RUNNING: 20 | running_node = child; 21 | return result; 22 | return Status.FAILED 23 | 24 | # Override 25 | func test(tick: Tick): 26 | return false; 27 | 28 | func reset(): 29 | .reset() 30 | running_node = null 31 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/switch.gd: -------------------------------------------------------------------------------- 1 | # 2 | # A state machine 3 | # 4 | 5 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 6 | 7 | export (int) var index setget set_index, get_index 8 | 9 | func tick(tick: Tick): 10 | var child = get_child(_index) 11 | if child is BNode: 12 | return child.run_tick(tick); 13 | return Status.FAILED 14 | 15 | func _request_focus(child: BNode): 16 | if child.get_parent() == self: 17 | var idx = get_children().find(child) 18 | if idx != _index: 19 | reset() 20 | _index = idx 21 | 22 | func debug_data(): 23 | return { 24 | "index": _index 25 | } 26 | 27 | var _index = 0 28 | 29 | func set_index(v): 30 | if _index != v: 31 | var subnode = get_child(_index) 32 | _index = v 33 | subnode.reset() 34 | 35 | func get_index(): 36 | return _index 37 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/if.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/if.png-fa328420f9c8c3f70f1d9f84753e18d1.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/if.png" 13 | dest_files=[ "res://.import/if.png-fa328420f9c8c3f70f1d9f84753e18d1.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/char.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/char.png-33b1ff4a0cc9e7b80e9b6b928a04f804.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/demo/char.png" 13 | dest_files=[ "res://.import/char.png-33b1ff4a0cc9e7b80e9b6b928a04f804.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/goto.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/goto.png-2d8834e775d62ec67311667048cd3573.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/goto.png" 13 | dest_files=[ "res://.import/goto.png-2d8834e775d62ec67311667048cd3573.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/link.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/link.png-5a61baaa0632e8174fb73a91fe504b10.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/link.png" 13 | dest_files=[ "res://.import/link.png-5a61baaa0632e8174fb73a91fe504b10.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/queue.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/queue.png-b47c4f8f4ee212f116bd823da687fe12.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/queue.png" 13 | dest_files=[ "res://.import/queue.png-b47c4f8f4ee212f116bd823da687fe12.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/stick.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/stick.png-5ebf64e2232b14ead3abbdadc07339ad.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/demo/stick.png" 13 | dest_files=[ "res://.import/stick.png-5ebf64e2232b14ead3abbdadc07339ad.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/action.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/action.png-8583a30519e8153bebbb57058d03c15a.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/action.png" 13 | dest_files=[ "res://.import/action.png-8583a30519e8153bebbb57058d03c15a.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/b_node.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/b_node.png-c9a6b596e3d1d55dd27667650aaf34d8.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/b_node.png" 13 | dest_files=[ "res://.import/b_node.png-c9a6b596e3d1d55dd27667650aaf34d8.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/period.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/period.png-fa285b7e3a470474ab1112749de056d2.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/period.png" 13 | dest_files=[ "res://.import/period.png-fa285b7e3a470474ab1112749de056d2.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/select.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/select.png-1889956af31820f0b9bc97fdbbc5f494.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/select.png" 13 | dest_files=[ "res://.import/select.png-1889956af31820f0b9bc97fdbbc5f494.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/switch.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/switch.png-67d792a750b38dda2d80024ed380d78e.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/switch.png" 13 | dest_files=[ "res://.import/switch.png-67d792a750b38dda2d80024ed380d78e.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/monitor.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/monitor.png-6d53767a10366938e2f52122081cff5e.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/monitor.png" 13 | dest_files=[ "res://.import/monitor.png-6d53767a10366938e2f52122081cff5e.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/running.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/running.png-74e99ade5745ddd4ccc06c5df5068999.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/running.png" 13 | dest_files=[ "res://.import/running.png-74e99ade5745ddd4ccc06c5df5068999.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=false 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/parallel.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/parallel.png-45836aaddd1fefc970ab45d764ec0568.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/parallel.png" 13 | dest_files=[ "res://.import/parallel.png-45836aaddd1fefc970ab45d764ec0568.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/sequence.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/sequence.png-1efba654cf43ec27a10f1bc55f9ab02e.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/sequence.png" 13 | dest_files=[ "res://.import/sequence.png-1efba654cf43ec27a10f1bc55f9ab02e.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/during_select.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/during_select.png-7ac98c28b52793bf8a323cad93e504ec.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/action_behavior_tree/lib/during_select.png" 13 | dest_files=[ "res://.import/during_select.png-7ac98c28b52793bf8a323cad93e504ec.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/queue.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | 3 | class TaskQueue: 4 | var children: Array 5 | var index = 0 6 | var inited = false 7 | 8 | func tick(tick): 9 | if index >= children.size(): 10 | return BNode.Status.FAILED 11 | 12 | var child:BNode = children[index] 13 | var result = child.run_tick(tick) 14 | if result != BNode.Status.RUNNING: 15 | index += 1 16 | if index < children.size(): 17 | result = BNode.Status.RUNNING 18 | return result 19 | 20 | var task_queue: TaskQueue = TaskQueue.new() 21 | 22 | func tick(tick: Tick): 23 | if not task_queue.inited: 24 | reset() 25 | 26 | var result = task_queue.tick(tick) 27 | if result != Status.RUNNING: 28 | task_queue.inited = false 29 | return result 30 | 31 | func _reset_queue(): 32 | task_queue.children.clear() 33 | for child in get_children(): 34 | if child is BNode: 35 | task_queue.children.append(child) 36 | task_queue.index = 0 37 | task_queue.inited = true 38 | 39 | func reset(): 40 | .reset() 41 | _reset_queue() 42 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/during_select.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | 3 | var _priority:BNode = null 4 | var _selected:BNode = null 5 | 6 | func tick(tick): 7 | if _selected != null: 8 | var result = _selected.run_tick(tick); 9 | if result != Status.RUNNING: 10 | _selected = null 11 | return result 12 | else: 13 | var priority_node = _priority 14 | _priority = null 15 | if priority_node is BNode: 16 | var result = priority_node.run_tick(tick) 17 | if result == Status.RUNNING: 18 | _selected = priority_node 19 | if result != Status.FAILED: 20 | return result 21 | for child in get_children(): 22 | if child is BNode and child != priority_node: 23 | var result = child.run_tick(tick) 24 | if result == Status.RUNNING: 25 | _selected = child 26 | if result != Status.FAILED: 27 | return result 28 | return Status.FAILED 29 | 30 | 31 | func reset(): 32 | .reset() 33 | _selected = null 34 | 35 | func _request_focus(child: BNode): 36 | if _selected != child and child.get_parent() == self: 37 | reset() 38 | _priority = child 39 | 40 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 gsioteam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/follow.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/action.gd" 2 | 3 | export(float) var distence = 24 4 | const speed = 50 5 | 6 | var _old_speed 7 | var _run_count = 0 8 | 9 | func tick(tick): 10 | if _old_speed == null: 11 | var target = tick.global_context["focus"] 12 | var direct:Vector2 = tick.target.position - target.position 13 | var tar_pos:Vector2 = target.position + direct.normalized() * distence 14 | var off = tar_pos - tick.target.position 15 | if abs(off.x) > abs(off.y): 16 | if off.x > 0: 17 | tick.target.rotation = deg2rad(90) 18 | _old_speed = Vector2(speed, 0) 19 | _run_count = 0 20 | else: 21 | tick.target.rotation = deg2rad(270) 22 | _old_speed = Vector2(-speed, 0) 23 | _run_count = 0 24 | else: 25 | if off.y > 0: 26 | tick.target.rotation = deg2rad(180) 27 | _old_speed = Vector2(0, speed) 28 | _run_count = 0 29 | else: 30 | tick.target.rotation = deg2rad(0) 31 | _old_speed = Vector2(0, -speed) 32 | _run_count = 0 33 | if _old_speed != null: 34 | tick.target.move_and_slide(_old_speed) 35 | _run_count += 1 36 | if _run_count > 10: 37 | _old_speed = null 38 | return Status.RUNNING 39 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/group_node.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends "res://addons/action_behavior_tree/lib/b_node.gd" 3 | 4 | var children_count = 0; 5 | 6 | func _ready(): 7 | if children_count > 0 && get_child_count() != children_count: 8 | push_warning(str("Children count(", children_count, ") is not match.")); 9 | 10 | func _get_configuration_warning(): 11 | if children_count > 0 && children_count != get_child_count(): 12 | return str("Children count(", children_count, ") is not match.") 13 | return "" 14 | 15 | func find_first() -> BNode: 16 | for child in get_children(): 17 | if child is BNode: 18 | return child 19 | return null 20 | 21 | func reset(): 22 | .reset() 23 | for child in get_children(): 24 | if child is BNode: 25 | child.reset() 26 | 27 | func get_root_node() -> BNode: 28 | var parent = get_parent_node() 29 | if parent == null: 30 | return self 31 | return parent.get_root_node() 32 | 33 | func get_parent_node() -> BNode: 34 | var parent = get_parent() 35 | if parent is BNode: 36 | return parent 37 | return null 38 | 39 | func require_focus(): 40 | var child = self 41 | var parent = get_parent_node() 42 | while parent != null: 43 | parent._request_focus(child) 44 | child = parent 45 | parent = parent.get_parent_node() 46 | 47 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/charactor.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody2D 2 | 3 | const BNode = preload("res://addons/action_behavior_tree/lib/b_node.gd") 4 | const HitState = preload("res://addons/action_behavior_tree/demo/hit_state.gd") 5 | 6 | var tick = null 7 | export var speed = Vector2() 8 | var hit_state: HitState 9 | var hit_from 10 | 11 | # Called when the node enters the scene tree for the first time. 12 | func _ready(): 13 | tick = BNode.Tick.new(self) 14 | set_meta("type", "Character") 15 | 16 | # Called every frame. 'delta' is the elapsed time since the previous frame. 17 | func _physics_process(delta): 18 | $behav.run_tick(tick) 19 | tick.end_frame() 20 | if speed != Vector2(): 21 | move_and_slide(Vector2(speed.x, -speed.y).rotated(rotation)) 22 | 23 | func play_anim(name): 24 | $anim.play(name) 25 | yield($anim, "animation_finished") 26 | 27 | func attack(state: HitState, hit_bodis: Array): 28 | var hti = false 29 | if $weapon/area.visible: 30 | var bodis = $weapon/area.get_overlapping_bodies() 31 | for body in bodis: 32 | if body.get_meta("type") == "Character" and not hit_bodis.has(body): 33 | hit_bodis.append(body) 34 | body.hit(state, self) 35 | hti = true 36 | return hti 37 | 38 | func hit(state: HitState, from): 39 | $behav.reset() 40 | hit_state = state 41 | hit_from = from 42 | 43 | func get_sprite(): 44 | return $sprite 45 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://addons/action_behavior_tree/demo/enemy.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://addons/action_behavior_tree/demo/char.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://addons/action_behavior_tree/lib/monitor.gd" type="Script" id=3] 6 | 7 | [sub_resource type="GDScript" id=1] 8 | script/source = "extends Node2D 9 | 10 | 11 | # Declare member variables here. Examples: 12 | # var a = 2 13 | # var b = \"text\" 14 | 15 | 16 | # Called when the node enters the scene tree for the first time. 17 | func _ready(): 18 | pass 19 | 20 | 21 | # Called every frame. 'delta' is the elapsed time since the previous frame. 22 | #func _process(delta): 23 | # pass 24 | 25 | 26 | func _on_Button_pressed(): 27 | var size = get_viewport_rect().size 28 | $window.popup(Rect2(0, 0, size.x / 2, size.y / 2)) 29 | " 30 | 31 | [node name="main" type="Node2D"] 32 | position = Vector2( 470, 300 ) 33 | script = SubResource( 1 ) 34 | 35 | [node name="Button" type="Button" parent="."] 36 | margin_left = -467.0 37 | margin_top = -296.0 38 | margin_right = -368.0 39 | margin_bottom = -276.0 40 | text = "Show Monitor" 41 | 42 | [node name="window" type="WindowDialog" parent="."] 43 | margin_left = -289.0 44 | margin_top = -124.0 45 | margin_right = -241.0 46 | margin_bottom = -84.0 47 | resizable = true 48 | 49 | [node name="Monitor" type="GraphEdit" parent="window"] 50 | anchor_right = 1.0 51 | anchor_bottom = 1.0 52 | use_snap = false 53 | minimap_enabled = false 54 | script = ExtResource( 3 ) 55 | target_path = NodePath("../../enemy/behav") 56 | 57 | [node name="enemy" parent="." instance=ExtResource( 1 )] 58 | position = Vector2( 49, -16 ) 59 | 60 | [node name="char" parent="." instance=ExtResource( 2 )] 61 | position = Vector2( -332, 219 ) 62 | 63 | [connection signal="pressed" from="Button" to="." method="_on_Button_pressed"] 64 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/b_node.gd: -------------------------------------------------------------------------------- 1 | 2 | extends Node 3 | class_name BNode, "res://addons/action_behavior_tree/lib/b_node.png" 4 | 5 | enum Status { 6 | RUNNING = 0, 7 | SUCCEED = 1, 8 | FAILED = -1, 9 | } 10 | 11 | class FrameListener: 12 | var count: int = 1 13 | 14 | signal completed 15 | 16 | func _init(count): 17 | self.count = count 18 | 19 | func tick(): 20 | count -= 1 21 | if count <= 0: 22 | emit_signal("completed") 23 | return true 24 | return false 25 | 26 | var last_status = -1 27 | var frame = 0 28 | var frame_listeners = [] 29 | 30 | var _last_frame = false 31 | 32 | var ticking = false 33 | 34 | export (bool) var enable = true 35 | 36 | class Tick: 37 | var target 38 | var frame_context: Dictionary 39 | var global_context: Dictionary 40 | 41 | func _init(target): 42 | frame_context = {} 43 | global_context = {} 44 | self.target = target 45 | 46 | func end_frame(): 47 | frame_context.clear() 48 | 49 | func has_new(): 50 | var active = _last_frame 51 | _last_frame = false 52 | return active 53 | 54 | func tick(tick: Tick): 55 | return Status.SUCCEED 56 | 57 | func post_tick(tick: Tick): 58 | pass 59 | 60 | func run_tick(tick: Tick): 61 | if not enable: 62 | return Status.FAILED 63 | ticking = true 64 | var need_remove = [] 65 | for listener in frame_listeners: 66 | if listener.tick(): 67 | need_remove.append(listener) 68 | for listener in need_remove: 69 | frame_listeners.erase(listener) 70 | var new_status = self.tick(tick) 71 | if new_status == null: 72 | new_status = Status.FAILED 73 | if last_status != new_status: 74 | last_status = new_status 75 | if new_status != Status.RUNNING: 76 | frame = 0 77 | if new_status == Status.RUNNING: 78 | frame += 1 79 | post_tick(tick) 80 | _last_frame = true 81 | ticking = false 82 | return last_status 83 | 84 | func reset(): 85 | frame = 0 86 | frame_listeners.clear() 87 | 88 | func wait(frame: int) -> FrameListener: 89 | var listener = FrameListener.new(frame) 90 | frame_listeners.append(listener) 91 | return listener 92 | 93 | func get_root_node() -> BNode: 94 | return null 95 | 96 | func get_parent_node() -> BNode: 97 | return null 98 | 99 | func debug_data() -> Dictionary: 100 | return {} 101 | 102 | func _request_focus(child: BNode): 103 | pass 104 | 105 | func require_focus(): 106 | pass 107 | 108 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/action.gd: -------------------------------------------------------------------------------- 1 | extends "res://addons/action_behavior_tree/lib/group_node.gd" 2 | 3 | const Running = preload('res://addons/action_behavior_tree/lib/running.gd') 4 | 5 | var running_child:BNode = null 6 | 7 | class RunningTask: 8 | var result = null 9 | var frame = 0 10 | var reset = false 11 | 12 | func _init(task: GDScriptFunctionState): 13 | var ret = yield(task, "completed") 14 | while ret is GDScriptFunctionState: 15 | ret = yield(ret, "completed") 16 | result = ret 17 | 18 | func tick(): 19 | frame += 1 20 | if result == null: 21 | return BNode.Status.RUNNING 22 | else: 23 | return result 24 | 25 | var process: RunningTask = null 26 | var _running: Running 27 | 28 | func _ready(): 29 | for child in get_children(): 30 | if child is Running: 31 | _running = child 32 | break 33 | 34 | func _init(): 35 | children_count = 0 36 | 37 | func tick(tick): 38 | if running_child != null: 39 | var result = running_child.run_tick(tick) 40 | if result != Status.RUNNING: 41 | running_child = null 42 | return result 43 | if process == null: 44 | var status = _run_action(tick); 45 | if status != Status.FAILED and _running != null: 46 | _running.tick(tick) 47 | return status 48 | else: 49 | var frame = process.frame 50 | var status = process.tick() 51 | if status == Status.RUNNING: 52 | running(tick, frame) 53 | if _running != null: 54 | _running.tick(tick) 55 | else: 56 | process = null 57 | stop_running() 58 | if can_cancel(tick, frame): 59 | for child in get_children(): 60 | if child is BNode: 61 | var result = child.run_tick(tick) 62 | match result: 63 | Status.RUNNING: 64 | enter_subaction(tick, child) 65 | running_child = child 66 | status = result 67 | process = null 68 | stop_running() 69 | Status.SUCCEED: 70 | enter_subaction(tick, child) 71 | status = result 72 | process = null 73 | stop_running() 74 | return status 75 | 76 | func _run_action(tick: Tick): 77 | var result = action(tick); 78 | if result is GDScriptFunctionState: 79 | process = RunningTask.new(result) 80 | return process.tick() 81 | return result; 82 | 83 | # Override 84 | # If the result of this method is `GDScriptFunctionState` 85 | # before it is completed, the result of `tick` will be `RUNNING`. 86 | func action(tick: Tick): 87 | return Status.FAILED 88 | 89 | func can_cancel(tick: Tick, frame: int): 90 | return false 91 | 92 | func running(tick: Tick, frame: int): 93 | pass 94 | 95 | func stop_running(): 96 | pass 97 | 98 | func process_child(child, tick): 99 | while true: 100 | var result = child.run_tick(tick); 101 | if result == Status.RUNNING: 102 | yield() 103 | else: 104 | return result 105 | 106 | func reset(): 107 | .reset() 108 | if _running != null: 109 | _running.reset() 110 | running_child = null 111 | if ticking: 112 | if process != null: 113 | process.reset = true 114 | else: 115 | process = null 116 | stop_running() 117 | 118 | func post_tick(tick): 119 | if process != null and process.reset: 120 | process = null 121 | stop_running() 122 | 123 | func enter_subaction(tick: Tick, subaction): 124 | pass 125 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/init.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends EditorPlugin 3 | 4 | 5 | func _enter_tree(): 6 | add_custom_type( 7 | "Select", 8 | "Node", 9 | preload("res://addons/action_behavior_tree/lib/select.gd"), 10 | preload("res://addons/action_behavior_tree/lib/select.png") 11 | ) 12 | add_custom_type( 13 | "Sequence", 14 | "Node", 15 | preload("res://addons/action_behavior_tree/lib/sequence.gd"), 16 | preload("res://addons/action_behavior_tree/lib/sequence.png") 17 | ) 18 | add_custom_type( 19 | "If", 20 | "Node", 21 | preload("res://addons/action_behavior_tree/lib/if.gd"), 22 | preload("res://addons/action_behavior_tree/lib/if.png") 23 | ) 24 | add_custom_type( 25 | "DuringSelect", 26 | "Node", 27 | preload("res://addons/action_behavior_tree/lib/during_select.gd"), 28 | preload("res://addons/action_behavior_tree/lib/during_select.png") 29 | ) 30 | add_custom_type( 31 | "Action", 32 | "Node", 33 | preload("res://addons/action_behavior_tree/lib/action.gd"), 34 | preload("res://addons/action_behavior_tree/lib/action.png") 35 | ) 36 | add_custom_type( 37 | "Parallel", 38 | "Node", 39 | preload("res://addons/action_behavior_tree/lib/parallel.gd"), 40 | preload("res://addons/action_behavior_tree/lib/parallel.png") 41 | ) 42 | add_custom_type( 43 | "Period", 44 | "Node", 45 | preload("res://addons/action_behavior_tree/lib/period.gd"), 46 | preload("res://addons/action_behavior_tree/lib/period.png") 47 | ) 48 | add_custom_type( 49 | "Probable", 50 | "Node", 51 | preload("res://addons/action_behavior_tree/lib/probable.gd"), 52 | preload("res://addons/action_behavior_tree/lib/if.png") 53 | ) 54 | add_custom_type( 55 | "Queue", 56 | "Node", 57 | preload("res://addons/action_behavior_tree/lib/queue.gd"), 58 | preload("res://addons/action_behavior_tree/lib/queue.png") 59 | ) 60 | add_custom_type( 61 | "Goto", 62 | "Node", 63 | preload("res://addons/action_behavior_tree/lib/goto.gd"), 64 | preload("res://addons/action_behavior_tree/lib/goto.png") 65 | ) 66 | add_custom_type( 67 | "Switch", 68 | "Node", 69 | preload("res://addons/action_behavior_tree/lib/switch.gd"), 70 | preload("res://addons/action_behavior_tree/lib/switch.png") 71 | ) 72 | add_custom_type( 73 | "Link", 74 | "Node", 75 | preload("res://addons/action_behavior_tree/lib/link.gd"), 76 | preload("res://addons/action_behavior_tree/lib/link.png") 77 | ) 78 | add_custom_type( 79 | "Monitor", 80 | "GraphEdit", 81 | preload("res://addons/action_behavior_tree/lib/monitor.gd"), 82 | preload("res://addons/action_behavior_tree/lib/monitor.png") 83 | ) 84 | add_custom_type( 85 | "Running", 86 | "Node", 87 | preload("res://addons/action_behavior_tree/lib/running.gd"), 88 | preload("res://addons/action_behavior_tree/lib/running.png") 89 | ) 90 | 91 | 92 | func _exit_tree(): 93 | remove_custom_type("Select") 94 | remove_custom_type("Sequence") 95 | remove_custom_type("If") 96 | remove_custom_type("DuringSelect") 97 | remove_custom_type("Action") 98 | remove_custom_type("Parallel") 99 | remove_custom_type("Period") 100 | remove_custom_type("Probable") 101 | remove_custom_type("Queue") 102 | remove_custom_type("Switch") 103 | remove_custom_type("Goto") 104 | remove_custom_type("Link") 105 | remove_custom_type("Monitor") 106 | remove_custom_type("Running") 107 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/lib/monitor.gd: -------------------------------------------------------------------------------- 1 | extends GraphEdit 2 | 3 | 4 | export(NodePath) var target_path 5 | 6 | const _Gap = 20 7 | const _Size = Vector2(100, 50) 8 | 9 | class NodeTree: 10 | var target: BNode 11 | var children: Array 12 | var _size 13 | var _node: GraphNode 14 | var _state_label: Label 15 | var _attributes: Dictionary = {} 16 | 17 | func _init(var target:BNode): 18 | self.target = target 19 | children = [] 20 | for child in target.get_children(): 21 | if child is BNode: 22 | children.append(NodeTree.new(child)) 23 | 24 | func setup(var editor: GraphEdit, var position: Vector2, parent_node: GraphNode = null): 25 | if _node == null: 26 | _node = GraphNode.new() 27 | _state_label = Label.new() 28 | _state_label.add_color_override("font_color", Color.white) 29 | _node.add_child(_state_label) 30 | _node.set_slot(0, true, 0, Color.white, true, 0, Color.white); 31 | _updateAttrbites() 32 | var parent = _node.get_parent() 33 | if parent != editor: 34 | if parent != null: 35 | parent.remove_child(_node) 36 | editor.add_child(_node) 37 | _node.set_size(_Size) 38 | _node.offset = position 39 | _node.title = target.name 40 | if parent_node == null: 41 | _node.name = target.name 42 | else: 43 | _node.name = str(parent_node.name, ">", target.name) 44 | editor.connect_node(parent_node.name, 0, _node.name, 0) 45 | 46 | var size = self.size() 47 | var offset = position + Vector2(_Size.x + _Gap * 4, -size.y/2) 48 | for child in children: 49 | var subsize = child.size() 50 | offset.y += subsize.y / 2 51 | child.setup(editor, offset, _node) 52 | offset.y += _Gap + subsize.y / 2; 53 | 54 | func size() -> Vector2: 55 | if _size == null: 56 | var subsize = Vector2(0,0) 57 | for child in children: 58 | var s = child.size() 59 | subsize.y += s.y + _Gap 60 | if s.x > subsize.x: 61 | subsize.x = s.x 62 | var dic = target.debug_data() 63 | var size = dic.keys().size() 64 | _size = Vector2(subsize.x + _Gap * 4 + _Size.x, max(subsize.y - _Gap, _Size.y + size * 20)) 65 | return _size 66 | 67 | func tick(): 68 | var state = BNode.Status.FAILED 69 | if target.has_new(): 70 | state = target.last_status 71 | match state: 72 | BNode.Status.FAILED: 73 | _state_label.text = "FAILED" 74 | _state_label.add_color_override("font_color", Color.white) 75 | _node.set_slot_color_left(0, Color.white) 76 | BNode.Status.RUNNING: 77 | _state_label.text = "RUNNING" 78 | _state_label.add_color_override("font_color", Color.green) 79 | _node.set_slot_color_left(0, Color.green) 80 | _updateAttrbites() 81 | BNode.Status.SUCCEED: 82 | _state_label.text = "SUCCEED" 83 | _state_label.add_color_override("font_color", Color.green) 84 | _node.set_slot_color_left(0, Color.green) 85 | _updateAttrbites() 86 | for child in children: 87 | child.tick() 88 | 89 | func _updateAttrbites(): 90 | var dic = target.debug_data() 91 | for key in dic.keys(): 92 | var value = dic[key] 93 | if _attributes.has(key): 94 | _attributes[key].text = str(value) 95 | else: 96 | var slot = HBoxContainer.new() 97 | var name_label = Label.new() 98 | name_label.text = str(key) 99 | slot.add_child(name_label) 100 | var value_label = Label.new() 101 | value_label.text = str(value) 102 | slot.add_child(value_label) 103 | _node.add_child(slot) 104 | _attributes[key] = value_label 105 | pass 106 | 107 | var tree 108 | 109 | func _ready(): 110 | var target = get_node(target_path) 111 | if (target != null): 112 | tree = _setupTree(target) 113 | tree.setup(self, Vector2(0,0)) 114 | 115 | func _setupTree(target) -> NodeTree: 116 | return NodeTree.new(target) 117 | 118 | func _physics_process(delta): 119 | if tree != null: 120 | tree.tick() 121 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/char.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=18 format=2] 2 | 3 | [ext_resource path="res://addons/action_behavior_tree/demo/charactor.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/action_behavior_tree/demo/anim.tscn" type="PackedScene" id=2] 5 | [ext_resource path="res://addons/action_behavior_tree/demo/stick.png" type="Texture" id=3] 6 | [ext_resource path="res://addons/action_behavior_tree/demo/key_down.gd" type="Script" id=4] 7 | [ext_resource path="res://addons/action_behavior_tree/lib/select.gd" type="Script" id=5] 8 | [ext_resource path="res://addons/action_behavior_tree/demo/hit.gd" type="Script" id=6] 9 | [ext_resource path="res://addons/action_behavior_tree/lib/during_select.gd" type="Script" id=7] 10 | [ext_resource path="res://addons/action_behavior_tree/demo/check_hit.gd" type="Script" id=8] 11 | [ext_resource path="res://addons/action_behavior_tree/demo/forward.tscn" type="PackedScene" id=9] 12 | [ext_resource path="res://addons/action_behavior_tree/demo/char.png" type="Texture" id=10] 13 | [ext_resource path="res://addons/action_behavior_tree/demo/attack.gd" type="Script" id=11] 14 | [ext_resource path="res://addons/action_behavior_tree/demo/hit_state.gd" type="Script" id=12] 15 | 16 | [sub_resource type="CircleShape2D" id=2] 17 | radius = 40.0 18 | 19 | [sub_resource type="Theme" id=9] 20 | Label/colors/font_color = Color( 0.968627, 1, 0, 1 ) 21 | Label/fonts/font = null 22 | 23 | [sub_resource type="RectangleShape2D" id=7] 24 | extents = Vector2( 4.61632, 30.9998 ) 25 | 26 | [sub_resource type="Resource" id=4] 27 | script = ExtResource( 12 ) 28 | power = 3.0 29 | speed = Vector2( 0, -60 ) 30 | 31 | [sub_resource type="Resource" id=5] 32 | script = ExtResource( 12 ) 33 | power = 3.0 34 | speed = Vector2( 0, -60 ) 35 | 36 | [node name="char" type="KinematicBody2D"] 37 | scale = Vector2( 0.2, 0.2 ) 38 | script = ExtResource( 1 ) 39 | 40 | [node name="CollisionShape2D" type="CollisionShape2D" parent="."] 41 | shape = SubResource( 2 ) 42 | 43 | [node name="Sprite" type="Sprite" parent="."] 44 | texture = ExtResource( 10 ) 45 | 46 | [node name="anim" parent="." instance=ExtResource( 2 )] 47 | 48 | [node name="alert" type="Node2D" parent="."] 49 | visible = false 50 | position = Vector2( 90, -140 ) 51 | scale = Vector2( 12, 12 ) 52 | 53 | [node name="Label" type="Label" parent="alert"] 54 | theme = SubResource( 9 ) 55 | text = "!" 56 | __meta__ = { 57 | "_edit_use_anchors_": false 58 | } 59 | 60 | [node name="weapon" type="Sprite" parent="."] 61 | visible = false 62 | position = Vector2( -84, -57 ) 63 | rotation = -0.911442 64 | texture = ExtResource( 3 ) 65 | 66 | [node name="area" type="Area2D" parent="weapon"] 67 | 68 | [node name="CollisionShape2D" type="CollisionShape2D" parent="weapon/area"] 69 | position = Vector2( -0.464804, -4.38504 ) 70 | rotation = 1.19209e-07 71 | shape = SubResource( 7 ) 72 | 73 | [node name="behav" type="Node" parent="."] 74 | script = ExtResource( 5 ) 75 | 76 | [node name="check_hit" type="Node" parent="behav"] 77 | script = ExtResource( 8 ) 78 | 79 | [node name="hit" type="Node" parent="behav/check_hit"] 80 | script = ExtResource( 6 ) 81 | 82 | [node name="control" type="Node" parent="behav"] 83 | script = ExtResource( 7 ) 84 | 85 | [node name="attack1" type="Node" parent="behav/control"] 86 | script = ExtResource( 4 ) 87 | action = "ui_accept" 88 | 89 | [node name="Action" type="Node" parent="behav/control/attack1"] 90 | script = ExtResource( 11 ) 91 | animation = "attack1" 92 | hit_state = SubResource( 4 ) 93 | 94 | [node name="attack2" type="Node" parent="behav/control/attack1/Action"] 95 | script = ExtResource( 4 ) 96 | action = "ui_accept" 97 | 98 | [node name="Action" type="Node" parent="behav/control/attack1/Action/attack2"] 99 | script = ExtResource( 11 ) 100 | animation = "attack2" 101 | hit_state = SubResource( 5 ) 102 | 103 | [node name="move" type="Node" parent="behav/control"] 104 | script = ExtResource( 5 ) 105 | 106 | [node name="up" type="Node" parent="behav/control/move"] 107 | script = ExtResource( 4 ) 108 | action = "ui_up" 109 | 110 | [node name="Forward" parent="behav/control/move/up" instance=ExtResource( 9 )] 111 | speed = 120.0 112 | 113 | [node name="right" type="Node" parent="behav/control/move"] 114 | script = ExtResource( 4 ) 115 | action = "ui_right" 116 | 117 | [node name="Forward" parent="behav/control/move/right" instance=ExtResource( 9 )] 118 | angle = 90 119 | speed = 120.0 120 | 121 | [node name="down" type="Node" parent="behav/control/move"] 122 | script = ExtResource( 4 ) 123 | action = "ui_down" 124 | 125 | [node name="Forward" parent="behav/control/move/down" instance=ExtResource( 9 )] 126 | angle = 180 127 | speed = 120.0 128 | 129 | [node name="left" type="Node" parent="behav/control/move"] 130 | script = ExtResource( 4 ) 131 | action = "ui_left" 132 | 133 | [node name="Forward" parent="behav/control/move/left" instance=ExtResource( 9 )] 134 | angle = 270 135 | speed = 120.0 136 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/enemy.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=19 format=2] 2 | 3 | [ext_resource path="res://addons/action_behavior_tree/demo/char.png" type="Texture" id=1] 4 | [ext_resource path="res://addons/action_behavior_tree/demo/stick.png" type="Texture" id=2] 5 | [ext_resource path="res://addons/action_behavior_tree/lib/probable.gd" type="Script" id=3] 6 | [ext_resource path="res://addons/action_behavior_tree/lib/select.gd" type="Script" id=4] 7 | [ext_resource path="res://addons/action_behavior_tree/demo/hit.gd" type="Script" id=5] 8 | [ext_resource path="res://addons/action_behavior_tree/demo/check_hit.gd" type="Script" id=6] 9 | [ext_resource path="res://addons/action_behavior_tree/demo/idle.gd" type="Script" id=7] 10 | [ext_resource path="res://addons/action_behavior_tree/demo/forward.tscn" type="PackedScene" id=8] 11 | [ext_resource path="res://addons/action_behavior_tree/lib/during_select.gd" type="Script" id=9] 12 | [ext_resource path="res://addons/action_behavior_tree/demo/charactor.gd" type="Script" id=10] 13 | [ext_resource path="res://addons/action_behavior_tree/lib/period.gd" type="Script" id=11] 14 | [ext_resource path="res://addons/action_behavior_tree/demo/anim.tscn" type="PackedScene" id=12] 15 | [ext_resource path="res://addons/action_behavior_tree/demo/scan.gd" type="Script" id=13] 16 | [ext_resource path="res://addons/action_behavior_tree/demo/attack.gd" type="Script" id=14] 17 | [ext_resource path="res://addons/action_behavior_tree/lib/queue.gd" type="Script" id=15] 18 | [ext_resource path="res://addons/action_behavior_tree/demo/follow.gd" type="Script" id=16] 19 | 20 | [sub_resource type="CircleShape2D" id=1] 21 | radius = 40.3113 22 | 23 | [sub_resource type="Theme" id=2] 24 | Label/colors/font_color = Color( 0.968627, 1, 0, 1 ) 25 | Label/fonts/font = null 26 | 27 | [node name="enemy" type="KinematicBody2D"] 28 | scale = Vector2( 0.2, 0.2 ) 29 | script = ExtResource( 10 ) 30 | 31 | [node name="scanner" type="Area2D" parent="."] 32 | 33 | [node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="scanner"] 34 | polygon = PoolVector2Array( 0, 0, 500, -1405, -500, -1405 ) 35 | 36 | [node name="CollisionShape2D" type="CollisionShape2D" parent="."] 37 | shape = SubResource( 1 ) 38 | 39 | [node name="sprite" type="Sprite" parent="."] 40 | texture = ExtResource( 1 ) 41 | 42 | [node name="alert" type="Node2D" parent="."] 43 | visible = false 44 | position = Vector2( 90, -140 ) 45 | scale = Vector2( 12, 12 ) 46 | 47 | [node name="Label" type="Label" parent="alert"] 48 | theme = SubResource( 2 ) 49 | text = "!" 50 | __meta__ = { 51 | "_edit_use_anchors_": false 52 | } 53 | 54 | [node name="anim" parent="." instance=ExtResource( 12 )] 55 | 56 | [node name="weapon" type="Sprite" parent="."] 57 | visible = false 58 | position = Vector2( -84, -57 ) 59 | rotation = -0.911442 60 | texture = ExtResource( 2 ) 61 | 62 | [node name="behav" type="Node" parent="."] 63 | script = ExtResource( 4 ) 64 | 65 | [node name="check_hit" type="Node" parent="behav"] 66 | script = ExtResource( 6 ) 67 | 68 | [node name="hit" type="Node" parent="behav/check_hit"] 69 | script = ExtResource( 5 ) 70 | 71 | [node name="control" type="Node" parent="behav"] 72 | script = ExtResource( 9 ) 73 | 74 | [node name="scan" type="Node" parent="behav/control"] 75 | script = ExtResource( 13 ) 76 | scanner = NodePath("../../../scanner") 77 | 78 | [node name="lock" type="Node" parent="behav/control/scan"] 79 | script = ExtResource( 15 ) 80 | 81 | [node name="alert" type="Node" parent="behav/control/scan/lock"] 82 | script = ExtResource( 14 ) 83 | animation = "alert" 84 | 85 | [node name="follow" type="Node" parent="behav/control/scan/lock"] 86 | script = ExtResource( 16 ) 87 | distence = 86.0 88 | 89 | [node name="Probable" type="Node" parent="behav/control"] 90 | script = ExtResource( 3 ) 91 | probability = 0.5 92 | 93 | [node name="idle" type="Node" parent="behav/control/Probable"] 94 | script = ExtResource( 7 ) 95 | 96 | [node name="walk_around" type="Node" parent="behav/control"] 97 | script = ExtResource( 9 ) 98 | 99 | [node name="up" type="Node" parent="behav/control/walk_around"] 100 | script = ExtResource( 3 ) 101 | probability = 0.25 102 | 103 | [node name="Period" type="Node" parent="behav/control/walk_around/up"] 104 | script = ExtResource( 11 ) 105 | duration = 60 106 | 107 | [node name="Forward" parent="behav/control/walk_around/up/Period" instance=ExtResource( 8 )] 108 | 109 | [node name="right" type="Node" parent="behav/control/walk_around"] 110 | script = ExtResource( 3 ) 111 | probability = 0.33 112 | 113 | [node name="Period" type="Node" parent="behav/control/walk_around/right"] 114 | script = ExtResource( 11 ) 115 | duration = 60 116 | 117 | [node name="Forward" parent="behav/control/walk_around/right/Period" instance=ExtResource( 8 )] 118 | angle = 90 119 | 120 | [node name="down" type="Node" parent="behav/control/walk_around"] 121 | script = ExtResource( 3 ) 122 | probability = 0.5 123 | 124 | [node name="Period" type="Node" parent="behav/control/walk_around/down"] 125 | script = ExtResource( 11 ) 126 | duration = 60 127 | 128 | [node name="Forward" parent="behav/control/walk_around/down/Period" instance=ExtResource( 8 )] 129 | angle = 180 130 | 131 | [node name="Period" type="Node" parent="behav/control/walk_around"] 132 | script = ExtResource( 11 ) 133 | duration = 60 134 | 135 | [node name="left" parent="behav/control/walk_around/Period" instance=ExtResource( 8 )] 136 | angle = 270 137 | -------------------------------------------------------------------------------- /addons/action_behavior_tree/demo/anim.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [sub_resource type="Animation" id=6] 4 | length = 0.001 5 | tracks/0/type = "value" 6 | tracks/0/path = NodePath("weapon:position") 7 | tracks/0/interp = 1 8 | tracks/0/loop_wrap = true 9 | tracks/0/imported = false 10 | tracks/0/enabled = true 11 | tracks/0/keys = { 12 | "times": PoolRealArray( 0 ), 13 | "transitions": PoolRealArray( 1 ), 14 | "update": 0, 15 | "values": [ Vector2( -84, -57 ) ] 16 | } 17 | tracks/1/type = "value" 18 | tracks/1/path = NodePath("weapon:rotation_degrees") 19 | tracks/1/interp = 1 20 | tracks/1/loop_wrap = true 21 | tracks/1/imported = false 22 | tracks/1/enabled = true 23 | tracks/1/keys = { 24 | "times": PoolRealArray( 0 ), 25 | "transitions": PoolRealArray( 1 ), 26 | "update": 0, 27 | "values": [ -52.2218 ] 28 | } 29 | tracks/2/type = "value" 30 | tracks/2/path = NodePath("weapon:scale") 31 | tracks/2/interp = 1 32 | tracks/2/loop_wrap = true 33 | tracks/2/imported = false 34 | tracks/2/enabled = true 35 | tracks/2/keys = { 36 | "times": PoolRealArray( 0 ), 37 | "transitions": PoolRealArray( 1 ), 38 | "update": 0, 39 | "values": [ Vector2( 1, 1 ) ] 40 | } 41 | tracks/3/type = "value" 42 | tracks/3/path = NodePath("weapon:visible") 43 | tracks/3/interp = 1 44 | tracks/3/loop_wrap = true 45 | tracks/3/imported = false 46 | tracks/3/enabled = true 47 | tracks/3/keys = { 48 | "times": PoolRealArray( 0 ), 49 | "transitions": PoolRealArray( 1 ), 50 | "update": 0, 51 | "values": [ false ] 52 | } 53 | tracks/4/type = "value" 54 | tracks/4/path = NodePath(".:speed") 55 | tracks/4/interp = 1 56 | tracks/4/loop_wrap = true 57 | tracks/4/imported = false 58 | tracks/4/enabled = true 59 | tracks/4/keys = { 60 | "times": PoolRealArray( 0 ), 61 | "transitions": PoolRealArray( 1 ), 62 | "update": 0, 63 | "values": [ Vector2( 0, 0 ) ] 64 | } 65 | tracks/5/type = "value" 66 | tracks/5/path = NodePath("alert:visible") 67 | tracks/5/interp = 1 68 | tracks/5/loop_wrap = true 69 | tracks/5/imported = false 70 | tracks/5/enabled = true 71 | tracks/5/keys = { 72 | "times": PoolRealArray( 0 ), 73 | "transitions": PoolRealArray( 1 ), 74 | "update": 0, 75 | "values": [ false ] 76 | } 77 | 78 | [sub_resource type="Animation" id=8] 79 | resource_name = "alert" 80 | step = 0.05 81 | tracks/0/type = "value" 82 | tracks/0/path = NodePath("alert:visible") 83 | tracks/0/interp = 1 84 | tracks/0/loop_wrap = true 85 | tracks/0/imported = false 86 | tracks/0/enabled = true 87 | tracks/0/keys = { 88 | "times": PoolRealArray( 0, 1 ), 89 | "transitions": PoolRealArray( 1, 1 ), 90 | "update": 1, 91 | "values": [ true, false ] 92 | } 93 | 94 | [sub_resource type="Animation" id=1] 95 | resource_name = "attack1" 96 | length = 0.533333 97 | step = 0.0333333 98 | tracks/0/type = "value" 99 | tracks/0/path = NodePath("weapon:position") 100 | tracks/0/interp = 1 101 | tracks/0/loop_wrap = true 102 | tracks/0/imported = false 103 | tracks/0/enabled = true 104 | tracks/0/keys = { 105 | "times": PoolRealArray( 0, 0.166667, 0.333333 ), 106 | "transitions": PoolRealArray( 1, 1, 1 ), 107 | "update": 0, 108 | "values": [ Vector2( -84, -57 ), Vector2( 2.38419e-07, -140 ), Vector2( 104, -27 ) ] 109 | } 110 | tracks/1/type = "value" 111 | tracks/1/path = NodePath("weapon:rotation_degrees") 112 | tracks/1/interp = 1 113 | tracks/1/loop_wrap = true 114 | tracks/1/imported = false 115 | tracks/1/enabled = true 116 | tracks/1/keys = { 117 | "times": PoolRealArray( 0, 0.166667, 0.333333 ), 118 | "transitions": PoolRealArray( 1, 1, 1 ), 119 | "update": 0, 120 | "values": [ -52.2218, -1.1216, 67.4081 ] 121 | } 122 | tracks/2/type = "value" 123 | tracks/2/path = NodePath("weapon:scale") 124 | tracks/2/interp = 1 125 | tracks/2/loop_wrap = true 126 | tracks/2/imported = false 127 | tracks/2/enabled = true 128 | tracks/2/keys = { 129 | "times": PoolRealArray( 0, 0.166667, 0.333333 ), 130 | "transitions": PoolRealArray( 1, 1, 1 ), 131 | "update": 0, 132 | "values": [ Vector2( 1, 1 ), Vector2( 1.32058, 2.02334 ), Vector2( 1, 1.52612 ) ] 133 | } 134 | tracks/3/type = "value" 135 | tracks/3/path = NodePath("weapon:visible") 136 | tracks/3/interp = 1 137 | tracks/3/loop_wrap = true 138 | tracks/3/imported = false 139 | tracks/3/enabled = true 140 | tracks/3/keys = { 141 | "times": PoolRealArray( 0, 0.333333 ), 142 | "transitions": PoolRealArray( 1, 1 ), 143 | "update": 1, 144 | "values": [ true, false ] 145 | } 146 | tracks/4/type = "value" 147 | tracks/4/path = NodePath(".:speed") 148 | tracks/4/interp = 1 149 | tracks/4/loop_wrap = true 150 | tracks/4/imported = false 151 | tracks/4/enabled = true 152 | tracks/4/keys = { 153 | "times": PoolRealArray( 0, 0.233333, 0.333333 ), 154 | "transitions": PoolRealArray( 1, 1, 1 ), 155 | "update": 0, 156 | "values": [ Vector2( 0, 0 ), Vector2( 0, 16 ), Vector2( 0, 0 ) ] 157 | } 158 | 159 | [sub_resource type="Animation" id=3] 160 | resource_name = "attack2" 161 | length = 0.533333 162 | step = 0.0333333 163 | tracks/0/type = "value" 164 | tracks/0/path = NodePath("weapon:visible") 165 | tracks/0/interp = 1 166 | tracks/0/loop_wrap = true 167 | tracks/0/imported = false 168 | tracks/0/enabled = true 169 | tracks/0/keys = { 170 | "times": PoolRealArray( 0, 0.4 ), 171 | "transitions": PoolRealArray( 1, 1 ), 172 | "update": 1, 173 | "values": [ true, false ] 174 | } 175 | tracks/1/type = "value" 176 | tracks/1/path = NodePath("weapon:position") 177 | tracks/1/interp = 1 178 | tracks/1/loop_wrap = true 179 | tracks/1/imported = false 180 | tracks/1/enabled = true 181 | tracks/1/keys = { 182 | "times": PoolRealArray( 0, 0.2, 0.4 ), 183 | "transitions": PoolRealArray( 1, 1, 1 ), 184 | "update": 0, 185 | "values": [ Vector2( 95, -40 ), Vector2( 0.0558292, -120.842 ), Vector2( -109.267, -31.2321 ) ] 186 | } 187 | tracks/2/type = "value" 188 | tracks/2/path = NodePath("weapon:rotation_degrees") 189 | tracks/2/interp = 1 190 | tracks/2/loop_wrap = true 191 | tracks/2/imported = false 192 | tracks/2/enabled = true 193 | tracks/2/keys = { 194 | "times": PoolRealArray( 0, 0.2, 0.4 ), 195 | "transitions": PoolRealArray( 1, 1, 1 ), 196 | "update": 0, 197 | "values": [ 57.7567, 0.153474, -70.7312 ] 198 | } 199 | tracks/3/type = "value" 200 | tracks/3/path = NodePath("weapon:scale") 201 | tracks/3/interp = 1 202 | tracks/3/loop_wrap = true 203 | tracks/3/imported = false 204 | tracks/3/enabled = true 205 | tracks/3/keys = { 206 | "times": PoolRealArray( 0, 0.2, 0.4 ), 207 | "transitions": PoolRealArray( 1, 1, 1 ), 208 | "update": 0, 209 | "values": [ Vector2( 1, 1 ), Vector2( 1, 1.65133 ), Vector2( 1.12256, 1.42599 ) ] 210 | } 211 | tracks/4/type = "value" 212 | tracks/4/path = NodePath(".:speed") 213 | tracks/4/interp = 1 214 | tracks/4/loop_wrap = true 215 | tracks/4/imported = false 216 | tracks/4/enabled = true 217 | tracks/4/keys = { 218 | "times": PoolRealArray( 0, 0.3, 0.4 ), 219 | "transitions": PoolRealArray( 1, 1, 1 ), 220 | "update": 0, 221 | "values": [ Vector2( 0, 0 ), Vector2( 0, 16 ), Vector2( 0, 0 ) ] 222 | } 223 | 224 | [node name="anim" type="AnimationPlayer"] 225 | anims/RESET = SubResource( 6 ) 226 | anims/alert = SubResource( 8 ) 227 | anims/attack1 = SubResource( 1 ) 228 | anims/attack2 = SubResource( 3 ) 229 | --------------------------------------------------------------------------------