优化技能命中 从单帧检测改为持续检测

master
chendian 9 months ago
parent 32b5343f1b
commit 9753cac24d

@ -12,65 +12,65 @@ var successful_index: int = 0
func tick(actor: Node, blackboard: Blackboard) -> int:
for c in get_children():
if c.get_index() < successful_index:
continue
if c != running_child:
c.before_run(actor, blackboard)
var response = c.tick(actor, blackboard)
if can_send_message(blackboard):
BeehaveDebuggerMessages.process_tick(c.get_instance_id(), response)
if c is ConditionLeaf:
blackboard.set_value("last_condition", c, str(actor.get_instance_id()))
blackboard.set_value("last_condition_status", response, str(actor.get_instance_id()))
match response:
SUCCESS:
_cleanup_running_task(c, actor, blackboard)
successful_index += 1
c.after_run(actor, blackboard)
FAILURE:
_cleanup_running_task(c, actor, blackboard)
# Interrupt any child that was RUNNING before.
interrupt(actor, blackboard)
c.after_run(actor, blackboard)
return FAILURE
RUNNING:
if c != running_child:
if running_child != null:
running_child.interrupt(actor, blackboard)
running_child = c
if c is ActionLeaf:
blackboard.set_value("running_action", c, str(actor.get_instance_id()))
return RUNNING
_reset()
return SUCCESS
for c in get_children():
if c.get_index() < successful_index:
continue
if c != running_child:
c.before_run(actor, blackboard)
var response = c.tick(actor, blackboard)
if can_send_message(blackboard):
BeehaveDebuggerMessages.process_tick(c.get_instance_id(), response)
if c is ConditionLeaf:
blackboard.set_value("last_condition", c, str(actor.get_instance_id()))
blackboard.set_value("last_condition_status", response, str(actor.get_instance_id()))
match response:
SUCCESS:
_cleanup_running_task(c, actor, blackboard)
successful_index += 1
c.after_run(actor, blackboard)
FAILURE:
_cleanup_running_task(c, actor, blackboard)
# Interrupt any child that was RUNNING before.
interrupt(actor, blackboard)
c.after_run(actor, blackboard)
return FAILURE
RUNNING:
if c != running_child:
if running_child != null:
running_child.interrupt(actor, blackboard)
running_child = c
if c is ActionLeaf:
blackboard.set_value("running_action", c, str(actor.get_instance_id()))
return RUNNING
_reset()
return SUCCESS
func interrupt(actor: Node, blackboard: Blackboard) -> void:
_reset()
super(actor, blackboard)
_reset()
super(actor, blackboard)
func _reset() -> void:
successful_index = 0
successful_index = 0
## Changes `running_action` and `running_child` after the node finishes executing.
func _cleanup_running_task(finished_action: Node, actor: Node, blackboard: Blackboard):
var blackboard_name = str(actor.get_instance_id())
if finished_action == running_child:
running_child = null
if finished_action == blackboard.get_value("running_action", null, blackboard_name):
blackboard.set_value("running_action", null, blackboard_name)
var blackboard_name = str(actor.get_instance_id())
if finished_action == running_child:
running_child = null
if finished_action == blackboard.get_value("running_action", null, blackboard_name):
blackboard.set_value("running_action", null, blackboard_name)
func get_class_name() -> Array[StringName]:
var classes := super()
classes.push_back(&"SequenceComposite")
return classes
var classes := super()
classes.push_back(&"SequenceComposite")
return classes

@ -1,10 +1,12 @@
@tool
extends EditorPlugin
var selected_skill_file: String
var menu_parent: Node
var skill_popup: PopupMenu
var short_cut_popup: PopupMenu
var skill_cfg_list: Array[SkillCfg]
var menu_parent: Node
var short_cut_path_list: Array[String]
var selected_skill_file: String
func _enter_tree():
@ -12,14 +14,32 @@ func _enter_tree():
while root.get_parent() != null:
root = root.get_parent()
menu_parent = root.get_child(0).get_child(4).get_child(0).get_child(0).get_child(0)
if menu_parent:
skill_popup = PopupMenu.new()
skill_popup.name = "技能配置"
skill_popup.about_to_popup.connect(skill_popup_about_to_popup)
skill_popup.index_pressed.connect(skill_popup_index_pressed)
menu_parent.add_child(skill_popup)
else:
if not menu_parent:
print("menu_parent is null")
return
## 技能配置
skill_popup = PopupMenu.new()
skill_popup.name = "技能配置"
menu_parent.add_child(skill_popup)
skill_popup.about_to_popup.connect(skill_popup_about_to_popup)
skill_popup.index_pressed.connect(skill_popup_index_pressed)
## 快捷方式
short_cut_popup = PopupMenu.new()
short_cut_popup.name = "快捷方式"
menu_parent.add_child(short_cut_popup)
short_cut_popup.index_pressed.connect(short_cut_index_pressed)
add_short_cut("配置-角色", "res://config/character")
add_short_cut("配置-武器技能", "res://config/skill_player_weapon")
add_short_cut("资产-技能特效", "res://scene/effect/particle")
add_short_cut("资产-AI", "res://scene/ai")
func add_short_cut(target_name: String, path: String):
short_cut_popup.add_item(target_name)
short_cut_path_list.append(path)
func skill_popup_about_to_popup():
@ -34,6 +54,10 @@ func skill_popup_index_pressed(index: int):
EditorInterface.select_file(skill_cfg_list[index].resource_path)
func short_cut_index_pressed(index: int):
EditorInterface.select_file(short_cut_path_list[index])
func _process(delta: float) -> void:
var selected_paths: PackedStringArray = EditorInterface.get_selected_paths()
if len(selected_paths) != 1:
@ -55,12 +79,17 @@ func _process(delta: float) -> void:
EditorInterface.open_scene_from_path("res://scene/character/character.tscn")
var root: Node = EditorInterface.get_edited_scene_root()
var character_skill: AnimationPlayer = root.find_child("Skill") as AnimationPlayer
EditorInterface.edit_node(character_skill)
var animation_name: String = "animation_library/%s" % Util.get_resource_name(res)
if not character_skill.has_animation(animation_name):
print("技能动画不存在:", animation_name)
return
character_skill.current_animation = animation_name
EditorInterface.edit_node(character_skill)
EditorInterface.edit_resource(res)
func _exit_tree():
remove_tool_menu_item("Test")
if skill_popup: skill_popup.queue_free()
if short_cut_popup: short_cut_popup.queue_free()

@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=3 format=3 uid="uid://bhxq1uffxyda8"]
[ext_resource type="Script" path="res://script/config/attack_box_cfg.gd" id="1_gwkwy"]
[ext_resource type="Script" uid="uid://dekrsow0vntqs" path="res://script/config/attack_box_cfg.gd" id="1_gwkwy"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_pmh6g"]
height = 0.25

@ -0,0 +1,15 @@
[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=3 format=3 uid="uid://df807k1y1vequ"]
[ext_resource type="Script" uid="uid://dekrsow0vntqs" path="res://script/config/attack_box_cfg.gd" id="1_fstin"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_pmh6g"]
height = 0.8
radius = 0.25
[resource]
script = ExtResource("1_fstin")
shape = SubResource("CylinderShape3D_pmh6g")
offset = Vector2(0, 0)
is_throw = false
is_direct = false
is_hit_self = true

@ -0,0 +1,29 @@
[gd_resource type="Resource" script_class="CharacterCfg" load_steps=9 format=3 uid="uid://cb4q16lmqwbin"]
[ext_resource type="PackedScene" uid="uid://bei75ysjq2pi4" path="res://scene/ai/bullet_simple.tscn" id="1_3q8i1"]
[ext_resource type="Resource" uid="uid://ckbf40c75bfqf" path="res://config/attack/sharp_normal_hit_up.tres" id="2_m73qf"]
[ext_resource type="Resource" uid="uid://decgfcx2xsj8i" path="res://config/attack_box/circle_mid.tres" id="3_3q8i1"]
[ext_resource type="Resource" uid="uid://iv8g1x3bkxvv" path="res://config/character_move/fast_fly.tres" id="4_2bsgq"]
[ext_resource type="Resource" uid="uid://dpajmgrlaytah" path="res://config/character_mp/normal.tres" id="5_gsbwd"]
[ext_resource type="Script" uid="uid://dt3chi1tgnaef" path="res://script/config/character_cfg.gd" id="6_1ypqo"]
[ext_resource type="Resource" uid="uid://h1curvk64vm3" path="res://config/character_shield/none.tres" id="7_k8icm"]
[ext_resource type="Resource" uid="uid://5jes0p152akr" path="res://config/character_stun/none.tres" id="8_rojoo"]
[resource]
script = ExtResource("6_1ypqo")
name = "hero01"
type = 2
sprite_height = 26
sprite_width = 16
move = ExtResource("4_2bsgq")
shield = ExtResource("7_k8icm")
stun = ExtResource("8_rojoo")
mp = ExtResource("5_gsbwd")
ai_behavior_tree = ExtResource("1_3q8i1")
hp_max = 100.0
attack = 1.0
attack1 = ExtResource("2_m73qf")
attack1_box = ExtResource("3_3q8i1")
sub_character_auto_create = false
material_on = 0
material_off = 0

@ -1,9 +1,9 @@
[gd_resource type="Resource" script_class="SkillCfg" load_steps=5 format=3 uid="uid://cwvj0xsv61cjk"]
[ext_resource type="Script" path="res://script/config/skill_cfg.gd" id="1_doifq"]
[ext_resource type="Script" uid="uid://ch4gg7uuu2e2t" path="res://script/config/skill_cfg.gd" id="1_doifq"]
[ext_resource type="Animation" uid="uid://h8hm3kbecdx8" path="res://resource/skill_animation/hero01_remote01.tres" id="2_h285p"]
[ext_resource type="SpriteFrames" uid="uid://ce83cuqwgwwi4" path="res://resource/animation/character/hero01_long_attack.aseprite" id="3_w10pb"]
[ext_resource type="Resource" uid="uid://d3mafsovw1mko" path="res://config/character/bullet02.tres" id="4_3k3a4"]
[ext_resource type="Resource" uid="uid://d3mafsovw1mko" path="res://config/character/bullet_hero01_soul_hit01.tres" id="4_3k3a4"]
[resource]
script = ExtResource("1_doifq")

@ -1,25 +0,0 @@
[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=4 format=3 uid="uid://djuch6s4ycecd"]
[ext_resource type="Script" path="res://script/config/skill_weapon_cfg.gd" id="1_pv5y3"]
[ext_resource type="Animation" uid="uid://5gj6dy1eysha" path="res://resource/skill_animation/hero01_basic_air_flash_back.tres" id="2_o1a71"]
[ext_resource type="SpriteFrames" uid="uid://jpxh0jr8wp8g" path="res://resource/animation/character/hero01_basic.aseprite" id="3_ti2km"]
[resource]
script = ExtResource("1_pv5y3")
action = "none"
name = ""
skill_animation = ExtResource("2_o1a71")
range = 0.0
free_lock = true
ignore_push = true
stance_from = 101
stance_to = 10
break_level = 1
is_charging = false
mp_cost = 0
warn_type = 0
with_stop = false
is_lock_x = null
refresh_animation = false
sprite_frames = ExtResource("3_ti2km")
animation_name = "basic_air_flash"

@ -1,26 +0,0 @@
[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=4 format=3 uid="uid://copd3b35mo2vn"]
[ext_resource type="Script" path="res://script/config/skill_weapon_cfg.gd" id="1_obmuu"]
[ext_resource type="Animation" uid="uid://bl2o7f7akp6if" path="res://resource/skill_animation/hero01_basic_flash_back.tres" id="2_cf3hj"]
[ext_resource type="SpriteFrames" uid="uid://jpxh0jr8wp8g" path="res://resource/animation/character/hero01_basic.aseprite" id="3_yxy1c"]
[resource]
script = ExtResource("1_obmuu")
action = "none"
name = ""
skill_animation = ExtResource("2_cf3hj")
range = 0.0
free_lock = true
ignore_push = true
stance_from = 100
stance_to = 0
break_level = 1
is_charging = false
mp_cost = 0
mp_sub_cost = false
warn_type = 0
with_stop = false
is_lock_x = true
refresh_animation = false
sprite_frames = ExtResource("3_yxy1c")
animation_name = "basic_flash"

@ -10,28 +10,27 @@
[resource]
script = ExtResource("3_0cjr8")
weapon = ExtResource("6_un8sq")
action = "attack_heavy"
action = "attack_light"
name = ""
skill_animation = ExtResource("4_mjivf")
range = 0.0
free_lock = false
ignore_push = true
stance_from = 30
stance_to = 30
break_level = 3
is_charging = false
attack1 = ExtResource("1_orvsj")
attack1_box = ExtResource("2_332ws")
attack1_with_pause_frame = false
attack1_with_stop = false
attack2_with_pause_frame = false
attack2_with_stop = false
stance_from = 30
stance_to = 30
break_level = 3
is_charging = false
mp_cost = 0
mp_sub_cost = false
warn_type = 0
free_lock = false
ignore_push = true
with_stop = false
is_lock_x = true
is_lock_x_move = true
refresh_animation = false
range = 0.0
warn_type = 0
sprite_frames = ExtResource("5_j4rp7")
animation_name = "long_skill_stab01"

@ -0,0 +1,36 @@
[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=7 format=3 uid="uid://fnub06pyo2l8"]
[ext_resource type="Resource" uid="uid://cw7rb4rlfw33q" path="res://config/attack/sharp_heavy_hit_back.tres" id="1_2k8jp"]
[ext_resource type="Resource" uid="uid://diedb7vw7eyxp" path="res://config/attack_box/box_mid.tres" id="2_1jdoh"]
[ext_resource type="Script" uid="uid://dgwtu2wj5033u" path="res://script/config/skill_weapon_cfg.gd" id="3_tbh7t"]
[ext_resource type="Animation" uid="uid://nhnwu6uccylr" path="res://resource/skill_animation/hero01_long_stab02.tres" id="4_2k8jp"]
[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="5_ys6gu"]
[ext_resource type="Resource" uid="uid://cy3wwalxeyro0" path="res://config/weapon/long.tres" id="6_3b28o"]
[resource]
script = ExtResource("3_tbh7t")
weapon = ExtResource("6_3b28o")
action = "none"
name = ""
skill_animation = ExtResource("4_2k8jp")
stance_from = 99
stance_to = 99
break_level = 0
is_charging = false
attack1 = ExtResource("1_2k8jp")
attack1_box = ExtResource("2_1jdoh")
attack1_with_pause_frame = false
attack1_with_stop = false
attack2_with_pause_frame = false
attack2_with_stop = false
mp_cost = 0
mp_sub_cost = false
free_lock = false
ignore_push = true
with_stop = false
is_lock_x = true
is_lock_x_move = true
range = 0.0
warn_type = 0
sprite_frames = ExtResource("5_ys6gu")
animation_name = "long_skill_stab02"

@ -0,0 +1,32 @@
[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=5 format=3 uid="uid://cjp4q8uhiryjd"]
[ext_resource type="Animation" uid="uid://qcmj7d5pg6lw" path="res://resource/skill_animation/hero01_short_skill01.tres" id="2_j0c0j"]
[ext_resource type="Script" uid="uid://dgwtu2wj5033u" path="res://script/config/skill_weapon_cfg.gd" id="3_0dcj8"]
[ext_resource type="SpriteFrames" uid="uid://dlmesk4xyydmd" path="res://resource/animation/character/hero01_short_skill03.aseprite" id="3_j0c0j"]
[ext_resource type="Resource" uid="uid://pnhii1a83axg" path="res://config/weapon/short.tres" id="6_7qlca"]
[resource]
script = ExtResource("3_0dcj8")
weapon = ExtResource("6_7qlca")
action = "attack_heavy"
name = ""
skill_animation = ExtResource("2_j0c0j")
stance_from = 1
stance_to = 30
break_level = 3
is_charging = false
attack1_with_pause_frame = false
attack1_with_stop = false
attack2_with_pause_frame = false
attack2_with_stop = false
mp_cost = 0
mp_sub_cost = false
free_lock = false
ignore_push = false
with_stop = false
is_lock_x = true
is_lock_x_move = false
range = 0.0
warn_type = 0
sprite_frames = ExtResource("3_j0c0j")
animation_name = "short_skill_stab01"

@ -0,0 +1,38 @@
[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=8 format=3 uid="uid://ckmsp5bdyk3tx"]
[ext_resource type="Resource" uid="uid://cuc04svaipss7" path="res://config/attack/sharp_normal_none.tres" id="1_5n6sn"]
[ext_resource type="Resource" uid="uid://diedb7vw7eyxp" path="res://config/attack_box/box_mid.tres" id="2_67ngl"]
[ext_resource type="Script" uid="uid://dgwtu2wj5033u" path="res://script/config/skill_weapon_cfg.gd" id="3_cub6b"]
[ext_resource type="Animation" uid="uid://b3fuombjh57oj" path="res://resource/skill_animation/hero01_short_stab01.tres" id="4_67ngl"]
[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="5_kk2vu"]
[ext_resource type="Resource" uid="uid://pnhii1a83axg" path="res://config/weapon/short.tres" id="6_5n6sn"]
[ext_resource type="Resource" uid="uid://cb4q16lmqwbin" path="res://config/character/bullet_hero01_short_stab01.tres" id="6_cub6b"]
[resource]
script = ExtResource("3_cub6b")
weapon = ExtResource("6_5n6sn")
action = "attack_light"
name = ""
sub_character = ExtResource("6_cub6b")
skill_animation = ExtResource("4_67ngl")
stance_from = 30
stance_to = 30
break_level = 3
is_charging = false
attack1 = ExtResource("1_5n6sn")
attack1_box = ExtResource("2_67ngl")
attack1_with_pause_frame = false
attack1_with_stop = false
attack2_with_pause_frame = false
attack2_with_stop = false
mp_cost = 0
mp_sub_cost = false
free_lock = false
ignore_push = true
with_stop = false
is_lock_x = true
is_lock_x_move = true
range = 0.0
warn_type = 0
sprite_frames = ExtResource("5_kk2vu")
animation_name = "long_skill_stab01"

@ -235,6 +235,12 @@ test_3={
]
}
[layer_names]
3d_physics/layer_1="墙体"
3d_physics/layer_2="角色"
3d_physics/layer_3="攻击框"
[memory]
limits/message_queue/max_size_mb=2048

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

@ -0,0 +1,25 @@
[remap]
importer="Aseprite SpriteFrames Import"
type="SpriteFrames"
uid="uid://dlmesk4xyydmd"
path="res://.godot/imported/hero01_short_skill03.aseprite-cf64863bc2c45d75bbeae9d71dcd4217.res"
[deps]
source_file="res://resource/animation/character/hero01_short_skill03.aseprite"
dest_files=["res://.godot/imported/hero01_short_skill03.aseprite-cf64863bc2c45d75bbeae9d71dcd4217.res"]
[params]
spritesheet/layout=0
spritesheet/fixed_rows_count=1
spritesheet/fixed_columns_count=1
spritesheet/border_type=0
spritesheet/trim=false
spritesheet/ignore_empty=false
spritesheet/merge_duplicates=false
animation/default/name="default"
animation/default/direction=0
animation/default/repeat_count=0
animation/autoplay=""

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cyw16jypnrjt0"
path="res://.godot/imported/hero01_short_skill03.png-8257420af302734e3238b32df28eecd2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resource/animation/character/hero01_short_skill03.png"
dest_files=["res://.godot/imported/hero01_short_skill03.png-8257420af302734e3238b32df28eecd2.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

@ -37,7 +37,7 @@ tracks/2/path = NodePath("Status:break_level")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.2),
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [3, 4]
@ -49,10 +49,10 @@ tracks/3/path = NodePath("Status:skill_move_speed")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.2),
"transitions": PackedFloat32Array(1, 1),
"times": PackedFloat32Array(0, 0.2, 0.3),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [7.0, 0.0]
"values": [7.0, 0.0, 1.0]
}
tracks/4/type = "method"
tracks/4/imported = false
@ -75,7 +75,7 @@ tracks/5/path = NodePath("Battle")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0.2),
"times": PackedFloat32Array(0.3),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
@ -89,7 +89,7 @@ tracks/6/path = NodePath("Status:is_speed_y_freeze")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(0, 0.2),
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [true, false]

@ -0,0 +1,95 @@
[gd_resource type="Animation" load_steps=2 format=3 uid="uid://nhnwu6uccylr"]
[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="1_yn72v"]
[resource]
resource_name = "hero01_long_stab02"
step = 0.1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("View:sprite_frames")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("1_yn72v")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("View:animation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": ["long_skill_stab02"]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Status:break_level")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.4, 0.7),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [0, 3, 4]
}
tracks/3/type = "method"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("Battle")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0.3),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"attack1"
}]
}
tracks/4/type = "method"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("Effect")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0.3),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"cast_attack_particle1"
}]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("View:frame")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}
tracks/6/type = "value"
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/path = NodePath("Status:skill_move_speed")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(0, 0.2, 0.3),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [-1.0, 4.0, 0.0]
}

@ -61,7 +61,7 @@ tracks/4/path = NodePath("Status:skill_move_speed")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0.1, 0.4, 0.6, 0.7),
"times": PackedFloat32Array(0, 0.4, 0.6, 0.7),
"transitions": PackedFloat32Array(1, 1, 1, 1),
"update": 1,
"values": [2.0, 0.0, 4.0, 0.0]
@ -130,3 +130,15 @@ tracks/7/keys = {
"update": 1,
"values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
}
tracks/8/type = "value"
tracks/8/imported = false
tracks/8/enabled = true
tracks/8/path = NodePath("Status:skill_float_speed")
tracks/8/interp = 1
tracks/8/loop_wrap = true
tracks/8/keys = {
"times": PackedFloat32Array(0.1, 0.2),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [2.0, 0.0]
}

@ -0,0 +1,82 @@
[gd_resource type="Animation" load_steps=2 format=3 uid="uid://qcmj7d5pg6lw"]
[ext_resource type="SpriteFrames" uid="uid://d1dgtfh3h3c24" path="res://resource/animation/character/hero01_short_skill01.aseprite" id="1_0x0f7"]
[resource]
resource_name = "hero01_short_skill01"
length = 0.8
step = 0.1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("View:sprite_frames")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("1_0x0f7")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("View:animation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": ["short_skill01"]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Status:skill_move_speed")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.2),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [-7.0, 0.0]
}
tracks/3/type = "method"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("Battle")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0.2),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"stop"
}]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("Status:break_level")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0, 0.2, 0.6),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [0, 3, 4]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("View:frame")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [0, 1, 2, 3, 4, 5, 6, 7]
}

@ -0,0 +1,95 @@
[gd_resource type="Animation" load_steps=2 format=3 uid="uid://b3fuombjh57oj"]
[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="1_rcy2y"]
[resource]
resource_name = "hero01_short_stab01"
length = 0.8
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("View:sprite_frames")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("1_rcy2y")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("View:animation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": ["long_skill_stab01"]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("View:frame")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [0, 1, 2, 3, 4, 5, 6, 7]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("Status:break_level")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.3, 0.5),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [0, 3, 4]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("Status:speed_up_rate")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0, 0.1),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [-0.5, -1.0]
}
tracks/5/type = "method"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("Battle")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0.1),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"cast_sub_character"
}]
}
tracks/6/type = "method"
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/path = NodePath("Effect")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(0.1),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"cast_attack_particle1"
}]
}

@ -1,4 +1,4 @@
[gd_resource type="AnimationLibrary" load_steps=53 format=3 uid="uid://croik07a1qko5"]
[gd_resource type="AnimationLibrary" load_steps=56 format=3 uid="uid://croik07a1qko5"]
[ext_resource type="Animation" uid="uid://t01a4jvp8srr" path="res://resource/skill_animation/hero01_fist_attack01.tres" id="1_4bwwm"]
[ext_resource type="Animation" uid="uid://cfapnjkj5dkws" path="res://resource/skill_animation/hero01_basic_flash.tres" id="1_46f01"]
@ -49,9 +49,12 @@
[ext_resource type="Animation" uid="uid://q7qlw0a7hfjt" path="res://resource/skill_animation/hero01_slash01.tres" id="38_lyels"]
[ext_resource type="Animation" uid="uid://b7f0rdven8gdc" path="res://resource/skill_animation/hero01_long_skill03.tres" id="42_d2bqv"]
[ext_resource type="Animation" uid="uid://cc086nunelk2q" path="res://resource/skill_animation/hero01_long_stab01.tres" id="43_0kutt"]
[ext_resource type="Animation" uid="uid://nhnwu6uccylr" path="res://resource/skill_animation/hero01_long_stab02.tres" id="44_c7cx4"]
[ext_resource type="Animation" uid="uid://2oxeq83bpofb" path="res://resource/skill_animation/monster03_slash02.tres" id="45_1vnur"]
[ext_resource type="Animation" uid="uid://dyyt3nsvoye62" path="res://resource/skill_animation/monster03_slash01.tres" id="45_s1ue4"]
[ext_resource type="Animation" uid="uid://co8bivpp1fm6g" path="res://resource/skill_animation/monster03_slash03.tres" id="46_litb8"]
[ext_resource type="Animation" uid="uid://qcmj7d5pg6lw" path="res://resource/skill_animation/hero01_short_skill01.tres" id="50_1hav4"]
[ext_resource type="Animation" uid="uid://b3fuombjh57oj" path="res://resource/skill_animation/hero01_short_stab01.tres" id="51_44mwa"]
[resource]
_data = {
@ -98,11 +101,14 @@ _data = {
&"hero01_long_skill02": ExtResource("7_ui68j"),
&"hero01_long_skill03": ExtResource("42_d2bqv"),
&"hero01_long_stab01": ExtResource("43_0kutt"),
&"hero01_long_stab02": ExtResource("44_c7cx4"),
&"hero01_remote01": ExtResource("33_7i37k"),
&"hero01_short_attack01": ExtResource("11_n0dhn"),
&"hero01_short_attack02": ExtResource("11_h2vlt"),
&"hero01_short_attack03": ExtResource("11_kejyu"),
&"hero01_short_attack04": ExtResource("11_bxi8a"),
&"hero01_short_skill01": ExtResource("50_1hav4"),
&"hero01_short_stab01": ExtResource("51_44mwa"),
&"hero01_slash01": ExtResource("38_lyels"),
&"monster03_slash01": ExtResource("45_s1ue4"),
&"monster03_slash02": ExtResource("45_1vnur"),

@ -1,86 +0,0 @@
[gd_scene load_steps=12 format=3 uid="uid://bgku27xawscbt"]
[ext_resource type="Script" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_r673b"]
[ext_resource type="Script" path="res://addons/beehave/nodes/composites/selector.gd" id="2_5ltau"]
[ext_resource type="Script" path="res://addons/beehave/nodes/composites/sequence.gd" id="3_yeaa5"]
[ext_resource type="Script" path="res://script/ai/action_blackboard/action_blackboard_check.gd" id="4_vnt1w"]
[ext_resource type="Script" path="res://script/ai/action/action_destroy.gd" id="5_0a0n1"]
[ext_resource type="Script" path="res://script/ai/action/action_wait.gd" id="6_omj7f"]
[ext_resource type="Script" path="res://script/ai/action_blackboard/action_blackboard_set.gd" id="7_gpffp"]
[ext_resource type="Script" path="res://script/ai/action/action_attack1.gd" id="7_wcjhl"]
[ext_resource type="Script" path="res://script/ai/action/action_stop_move.gd" id="8_ntwgo"]
[ext_resource type="Script" path="res://script/ai/action_blackboard/action_blackboard_add.gd" id="8_rm753"]
[ext_resource type="Script" path="res://addons/beehave/nodes/decorators/succeeder.gd" id="9_lh2cr"]
[node name="BeehaveTree" type="Node" node_paths=PackedStringArray("blackboard")]
script = ExtResource("1_r673b")
blackboard = NodePath("@Node@19481")
[node name="SelectorComposite" type="Node" parent="."]
script = ExtResource("2_5ltau")
[node name="SequenceComposite" type="Node" parent="SelectorComposite"]
script = ExtResource("3_yeaa5")
[node name="CheckStep0" type="Node" parent="SelectorComposite/SequenceComposite"]
script = ExtResource("4_vnt1w")
key = "step"
[node name="ActionWait" type="Node" parent="SelectorComposite/SequenceComposite"]
script = ExtResource("6_omj7f")
wait_time = 0.05
[node name="ActionAttack1" type="Node" parent="SelectorComposite/SequenceComposite"]
script = ExtResource("7_wcjhl")
[node name="ActionStopMove" type="Node" parent="SelectorComposite/SequenceComposite"]
script = ExtResource("8_ntwgo")
[node name="SetStep1" type="Node" parent="SelectorComposite/SequenceComposite"]
script = ExtResource("7_gpffp")
key = "step"
value = 1
[node name="SequenceComposite2" type="Node" parent="SelectorComposite"]
script = ExtResource("3_yeaa5")
[node name="CheckStep1" type="Node" parent="SelectorComposite/SequenceComposite2"]
script = ExtResource("4_vnt1w")
key = "step"
value = 1
[node name="ActionWait" type="Node" parent="SelectorComposite/SequenceComposite2"]
script = ExtResource("6_omj7f")
wait_time = 0.3
[node name="AlwaysSucceedDecorator" type="Node" parent="SelectorComposite/SequenceComposite2"]
script = ExtResource("9_lh2cr")
[node name="ActionAttack1" type="Node" parent="SelectorComposite/SequenceComposite2/AlwaysSucceedDecorator"]
script = ExtResource("7_wcjhl")
[node name="AddHit" type="Node" parent="SelectorComposite/SequenceComposite2"]
script = ExtResource("8_rm753")
key = "hit"
value = 1
[node name="CheckHit9" type="Node" parent="SelectorComposite/SequenceComposite2"]
script = ExtResource("4_vnt1w")
key = "hit"
value = 9
[node name="SetStep2" type="Node" parent="SelectorComposite/SequenceComposite2"]
script = ExtResource("7_gpffp")
key = "step"
value = 2
[node name="SequenceComposite3" type="Node" parent="SelectorComposite"]
script = ExtResource("3_yeaa5")
[node name="CheckStep2" type="Node" parent="SelectorComposite/SequenceComposite3"]
script = ExtResource("4_vnt1w")
key = "step"
value = 2
[node name="ActionDestroy" type="Node" parent="SelectorComposite/SequenceComposite3"]
script = ExtResource("5_0a0n1")

@ -1,23 +0,0 @@
[gd_scene load_steps=6 format=3 uid="uid://bdwwmat306mff"]
[ext_resource type="Script" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_go1b5"]
[ext_resource type="Script" path="res://addons/beehave/nodes/composites/sequence.gd" id="2_k8nph"]
[ext_resource type="Script" path="res://script/ai/action/action_stop_move.gd" id="3_aums8"]
[ext_resource type="Script" path="res://script/ai/action/action_attack1.gd" id="4_mhoc5"]
[ext_resource type="Script" path="res://script/ai/action/action_destroy.gd" id="5_ejojh"]
[node name="BeehaveTree" type="Node" node_paths=PackedStringArray("blackboard")]
script = ExtResource("1_go1b5")
blackboard = NodePath("@Node@19760")
[node name="SequenceComposite" type="Node" parent="."]
script = ExtResource("2_k8nph")
[node name="ActionStopMove" type="Node" parent="SequenceComposite"]
script = ExtResource("3_aums8")
[node name="ActionAttack1" type="Node" parent="SequenceComposite"]
script = ExtResource("4_mhoc5")
[node name="ActionDestroy" type="Node" parent="SequenceComposite"]
script = ExtResource("5_ejojh")

@ -0,0 +1,24 @@
[gd_scene load_steps=6 format=3 uid="uid://bei75ysjq2pi4"]
[ext_resource type="Script" uid="uid://mvwcxqcetiqp" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_7oi2o"]
[ext_resource type="Script" uid="uid://cugftmuc8v30c" path="res://addons/beehave/nodes/composites/sequence.gd" id="3_i33jf"]
[ext_resource type="Script" uid="uid://cnw25wdsd3c76" path="res://script/ai/action/action_wait.gd" id="5_onfb3"]
[ext_resource type="Script" uid="uid://ddcaceywxwt20" path="res://script/ai/action/action_attack1.gd" id="6_oqib4"]
[ext_resource type="Script" uid="uid://ci3tg5fkdn16f" path="res://script/ai/action/action_destroy.gd" id="11_i4mx4"]
[node name="BeehaveTree" type="Node" node_paths=PackedStringArray("blackboard")]
script = ExtResource("1_7oi2o")
blackboard = NodePath("@Node@25322")
[node name="SequenceComposite" type="Node" parent="."]
script = ExtResource("3_i33jf")
[node name="ActionWait" type="Node" parent="SequenceComposite"]
script = ExtResource("5_onfb3")
wait_time = 0.05
[node name="ActionAttack1" type="Node" parent="SequenceComposite"]
script = ExtResource("6_oqib4")
[node name="ActionDestroy" type="Node" parent="SequenceComposite"]
script = ExtResource("11_i4mx4")

@ -0,0 +1,20 @@
[gd_scene load_steps=5 format=3 uid="uid://tr65aikkpp2e"]
[ext_resource type="Script" uid="uid://mvwcxqcetiqp" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_6wcp2"]
[ext_resource type="Script" uid="uid://cugftmuc8v30c" path="res://addons/beehave/nodes/composites/sequence.gd" id="2_0p8p1"]
[ext_resource type="Script" uid="uid://cnw25wdsd3c76" path="res://script/ai/action/action_wait.gd" id="3_irjra"]
[ext_resource type="Script" uid="uid://ddcaceywxwt20" path="res://script/ai/action/action_attack1.gd" id="4_klwmg"]
[node name="BeehaveTree" type="Node" node_paths=PackedStringArray("blackboard")]
script = ExtResource("1_6wcp2")
blackboard = NodePath("@Node@25321")
[node name="SequenceComposite" type="Node" parent="."]
script = ExtResource("2_0p8p1")
[node name="ActionWait" type="Node" parent="SequenceComposite"]
script = ExtResource("3_irjra")
wait_time = 0.05
[node name="ActionAttack1" type="Node" parent="SequenceComposite"]
script = ExtResource("4_klwmg")

@ -1,15 +1,16 @@
[gd_scene load_steps=24 format=3 uid="uid://8rcvw1vnjcf7"]
[gd_scene load_steps=25 format=3 uid="uid://8rcvw1vnjcf7"]
[ext_resource type="Script" uid="uid://cdvtgxvof33j3" path="res://script/character/character.gd" id="1_tonbs"]
[ext_resource type="Script" uid="uid://cms637d0jt6sk" path="res://script/character/hitbox.gd" id="2_6xf87"]
[ext_resource type="Script" uid="uid://bfi4gneebe3oq" path="res://script/character/status.gd" id="2_txdip"]
[ext_resource type="SpriteFrames" uid="uid://cajgs8smbkjan" path="res://resource/animation/character/hero01_fist_skill01.aseprite" id="4_53b4u"]
[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="4_53b4u"]
[ext_resource type="Script" uid="uid://cnaqs44siwa45" path="res://script/character/move.gd" id="4_66r53"]
[ext_resource type="Script" uid="uid://c247mf44qb3uf" path="res://script/character/view.gd" id="4_vijjv"]
[ext_resource type="Script" uid="uid://c24is3uqqcmcn" path="res://script/character/skill.gd" id="6_h4xqy"]
[ext_resource type="AnimationLibrary" uid="uid://croik07a1qko5" path="res://resource/skill_animation_library/animation_library.tres" id="6_pakq5"]
[ext_resource type="Script" uid="uid://cxklw5xp85wuw" path="res://script/character/battle.gd" id="8_w84sf"]
[ext_resource type="Script" uid="uid://bys2rd62nmj2v" path="res://script/character/buff.gd" id="9_jlnhy"]
[ext_resource type="Script" uid="uid://dqsadncw4srh6" path="res://script/character/battle_attack_area.gd" id="11_sox5o"]
[ext_resource type="Script" uid="uid://d3lbbulqdp1nu" path="res://script/character/effect.gd" id="12_eyfcd"]
[ext_resource type="Script" uid="uid://b2ap8nlbb2717" path="res://script/character/core.gd" id="14_gua01"]
[ext_resource type="PackedScene" uid="uid://cq03usrdvv43o" path="res://scene/effect/readiness/readiness_lock.tscn" id="14_gw1pa"]
@ -57,6 +58,30 @@ tracks/1/keys = {
"update": 1,
"values": [false]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Status:skill_move_speed")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [2.0]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("Status:skill_float_speed")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.1]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_avnjy"]
_data = {
@ -100,6 +125,7 @@ shape = SubResource("CylinderShape3D_ehwx5")
unique_name_in_owner = true
script = ExtResource("2_txdip")
speed_up_rate = -0.5
skill_move_speed = 2.0
skill_float_speed = 0.1
[node name="View" type="AnimatedSprite3D" parent="."]
@ -112,7 +138,7 @@ pixel_size = 0.02
double_sided = false
texture_filter = 0
sprite_frames = ExtResource("4_53b4u")
animation = &"fist_skill03"
animation = &"long_skill_stab01"
script = ExtResource("4_vijjv")
[node name="Move" type="Node3D" parent="."]
@ -138,6 +164,16 @@ script = ExtResource("8_w84sf")
hit_back_limit_curve = SubResource("Curve_e7j3f")
pause_time_limit_curve = SubResource("Curve_55xfs")
[node name="BattleAttackArea" type="Area3D" parent="Battle"]
unique_name_in_owner = true
collision_layer = 4
collision_mask = 3
script = ExtResource("11_sox5o")
metadata/_custom_type_script = ExtResource("11_sox5o")
[node name="BattleAttackAreaCollision" type="CollisionShape3D" parent="Battle/BattleAttackArea"]
unique_name_in_owner = true
[node name="Effect" type="Node3D" parent="."]
unique_name_in_owner = true
script = ExtResource("12_eyfcd")

@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=3 uid="uid://bakftws1caca2"]
[ext_resource type="PackedScene" uid="uid://b2h4pcmlii7dg" path="res://scene/effect/particle/_particle_slash1.tscn" id="1_bduq8"]
[node name="Particle" instance=ExtResource("1_bduq8")]
transform = Transform3D(0.5, 0, 0, 0, 1, 0, 0, 0, 0.5, 0, 0, 0)
[node name="Slash" parent="." index="0"]
emitting = true
lifetime = 600.0
one_shot = false
seed = 300733846

@ -0,0 +1,15 @@
extends Node3D
class_name Struct
class AttackInfo:
var attack: AttackCfg
var attack_box: AttackBoxCfg
var attack_dir: Vector2 = Vector2.ZERO
var with_stop: bool = false
var ignore_push: bool = false
class HitResultInfo:
var is_hit: bool
var is_break: bool

@ -68,8 +68,6 @@ func raycast_character(shape: Shape3D, origin: Vector3, dir: Vector2) -> Array[C
var result3: Array[Character]
for node in result2:
result3.append(node as Character)
if result.size() > result3.size():
result3.append(null) #特殊处理 表示命中非Character物体 例如墙体或地面
return result3

@ -2,9 +2,6 @@ extends Action
class_name ActionAttack1
func run(character: Character, blackboard: Blackboard) -> int:
var is_hit: bool = character.attack1()
if is_hit:
return SUCCESS
else:
return FAILURE
character.attack1()
return SUCCESS

@ -2,9 +2,6 @@ extends Action
class_name ActionAttack2
func run(character: Character, blackboard: Blackboard) -> int:
var is_hit: bool = character.attack2()
if is_hit:
return SUCCESS
else:
return FAILURE
character.attack2()
return SUCCESS

@ -4,4 +4,4 @@ class_name ActionDestroy
func run(character: Character, blackboard: Blackboard) -> int:
Global.character_mgr.destroy_character(character.id())
return SUCCESS

@ -8,105 +8,78 @@ class_name Battle
@onready var status: Status = (%Status as Status)
@onready var skill: Skill = (%Skill as Skill)
@onready var move: Move = (%Move as Move)
class HitResult:
var is_hit: bool
var is_break: bool
@onready var battle_attack_area: BattleAttackArea = (%BattleAttackArea as BattleAttackArea)
func attack1() -> void:
if not status.skill_cfg:
return
var attack: AttackCfg = status.skill_cfg.get_attack1()
var attack_box: AttackBoxCfg = status.skill_cfg.get_attack1_box()
add_attack(attack, attack_box, false, Vector2.ZERO,
status.skill_cfg.attack1_with_pause_frame, status.skill_cfg.attack1_with_stop, status.skill_cfg.ignore_push)
var attack_info: Struct.AttackInfo = Struct.AttackInfo.new()
attack_info.attack = status.skill_cfg.get_attack1()
attack_info.attack_box = status.skill_cfg.get_attack1_box()
attack_info.attack_dir = status.skill_dir
attack_info.with_stop = status.skill_cfg.attack1_with_stop
attack_info.ignore_push = status.skill_cfg.ignore_push
add_attack(attack_info)
func attack2() -> void:
if not status.skill_cfg:
return
var attack: AttackCfg = status.skill_cfg.get_attack2()
var attack_box: AttackBoxCfg = status.skill_cfg.get_attack2_box()
add_attack(attack, attack_box, false, Vector2.ZERO,
status.skill_cfg.attack2_with_pause_frame, status.skill_cfg.attack2_with_stop, status.skill_cfg.ignore_push)
func character_attack1() -> bool:
var attack: AttackCfg = status.cfg.get_attack1()
var attack_box: AttackBoxCfg = status.cfg.get_attack1_box()
return add_attack(attack, attack_box)
func character_attack2() -> bool:
var attack: AttackCfg = status.cfg.get_attack2()
var attack_box: AttackBoxCfg = status.cfg.get_attack2_box()
return add_attack(attack, attack_box)
func add_attack(attack: AttackCfg, attack_box: AttackBoxCfg, hit_self: bool = false, attack_dir: Vector2 = Vector2.ZERO,
with_pause_frame: bool = false, with_stop: bool = false, ignore_push: bool = false) -> bool:
if not attack or not attack_box:
return false
var pos: Vector3 = character.pos()
if not attack_dir:
attack_dir = status.skill_dir.normalized()
var result: Array[Character]
if attack_box.is_throw:
var attack_info: Struct.AttackInfo = Struct.AttackInfo.new()
attack_info.attack = status.skill_cfg.get_attack2()
attack_info.attack_box = status.skill_cfg.get_attack2_box()
attack_info.attack_dir = status.skill_dir
attack_info.with_stop = status.skill_cfg.attack2_with_stop
attack_info.ignore_push = status.skill_cfg.ignore_push
add_attack(attack_info)
func character_attack1() -> void:
var attack_info: Struct.AttackInfo = Struct.AttackInfo.new()
attack_info.attack = status.cfg.get_attack1()
attack_info.attack_box = status.cfg.get_attack1_box()
attack_info.attack_dir = status.move_dir
add_attack(attack_info)
func character_attack2() -> void:
var attack_info: Struct.AttackInfo = Struct.AttackInfo.new()
attack_info.attack = status.cfg.get_attack2()
attack_info.attack_box = status.cfg.get_attack2_box()
attack_info.attack_dir = status.move_dir
add_attack(attack_info)
func add_attack(attack_info: Struct.AttackInfo) -> void:
var result: Character
if attack_info.attack_box.is_throw:
var target: Character = Global.character_mgr.get_character(status.throw_target)
if target:
result = [target]
elif attack_box.is_direct:
result = target
elif attack_info.attack_box.is_direct:
var target: Character = Global.character_mgr.get_character(status.target)
if target:
result = [target]
result = target
else:
var offset_xz: Vector2 = attack_dir * attack_box.offset.x
var offset_y: float = attack_box.offset.y
var offset: Vector3 = Vector3(offset_xz.x, offset_y, offset_xz.y)
var shape: Shape3D = attack_box.shape
if not shape:
print("无效形状:", attack_box.get_res_name())
_debug_draw_attack_box(shape, offset)
result = Util.raycast_character(shape, pos+offset, attack_dir)
#result按break_level_def排序 确保硬直最高的最后结算
result.sort_custom(
func(a: Character, b: Character):
if a == null: return true
if b == null: return false
return a.get_break_level_def() < b.get_break_level_def()
)
var is_hit: bool = false
for target: Character in result:
if target == null:
is_hit = true
continue
if hit_self != (target.team() == character.team()):
continue
var hit_result: HitResult = settle(character.id(), target.id(), attack_dir, attack, with_stop, ignore_push)
on_attack_hit(hit_result)
is_hit = true
if !is_hit and with_pause_frame:
skill.on_attack_miss()
return is_hit
func _debug_draw_attack_box(shape: Shape3D, offset: Vector3) -> void:
if not get_tree().debug_collisions_hint:
battle_attack_area.refresh_attack_area(attack_info)
return
if shape is BoxShape3D:
var scale: Vector3 = shape.size
character.cast_particle(ResourceManager.particle_debug_box, false, offset, scale)
elif shape is CylinderShape3D:
var scale: Vector3 = Vector3(shape.radius, shape.height, shape.radius)
character.cast_particle(ResourceManager.particle_debug_cylinder, false, offset, scale)
return
on_attack_character(result, attack_info)
func settle(from: int, to: int, dir: Vector2, attack: AttackCfg, with_stop: bool, ignore_push: bool) -> HitResult:
var hit_result: HitResult = HitResult.new()
func on_attack_character(result: Character, attack_info: Struct.AttackInfo) -> void:
if attack_info.attack_box.is_hit_self != (result.team() == character.team()):
return
var hit_result: Struct.HitResultInfo = settle(character.id(), result.id(), attack_info)
on_attack_hit(hit_result)
func settle(from: int, to: int, attack_info: Struct.AttackInfo) -> Struct.HitResultInfo:
var attack: AttackCfg = attack_info.attack
var attack_dir: Vector2 = attack_info.attack_dir
var with_stop: bool = attack_info.with_stop
var ignore_push: bool = attack_info.ignore_push
var hit_result: Struct.HitResultInfo = Struct.HitResultInfo.new()
var character_from: Character = Global.character_mgr.get_character(from) as Character
var character_to: Character = Global.character_mgr.get_character(to) as Character
@ -266,8 +239,8 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg, with_stop: bool
if is_floating:
character_to.add_buff("stagger", -1)
character_to.add_buff("floating", -1)
if dir.x!=0:
character_to.set_status("is_right", dir.x<0)
if attack_dir.x!=0:
character_to.set_status("is_right", attack_dir.x<0)
else:
match break_level_sub:
1: character_to.add_buff("stagger", 0.3)
@ -280,7 +253,7 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg, with_stop: bool
if not is_break_skill_real:
hit_up_speed *= 0.75
character_to.set_hit_move(dir, hit_back_speed, hit_up_speed)
character_to.set_hit_move(attack_dir, hit_back_speed, hit_up_speed)
character_to.add_buff("hit_back", attack.hit_back_duration)
character_to.add_buff("hit_up", attack.hit_up_duration)
@ -297,7 +270,7 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg, with_stop: bool
var self_hit_back_speed = max(hit_back_limit_curve.sample(dist_rate), 2)
character_from.move_stop()
character_from.set_status("skill_move_stop", true)
character_from.set_hit_move(-dir, self_hit_back_speed, 0)
character_from.set_hit_move(-attack_dir, self_hit_back_speed, 0)
character_from.add_buff("hit_back", attack.hit_up_duration)
#受击pt掉落
@ -461,26 +434,35 @@ func change_dir() -> void:
status.is_right = cast_dir.x > 0
func on_attack_hit(hit_result: HitResult) -> void:
func on_attack_hit(hit_result: Struct.HitResultInfo) -> void:
if not status.skill_cfg:
return
var skill_name: String = status.skill_cfg.get_res_name()
if hit_result.is_hit:
on_attack_hit_trigger(skill_name, "hit")
on_skill_trigger(skill_name, "hit")
if hit_result.is_break:
on_attack_hit_trigger(skill_name, "break")
on_skill_trigger(skill_name, "break")
func on_skill_release(skill_name: String) -> void:
on_skill_trigger(skill_name, "release")
func on_skill_cast(skill_name: String) -> void:
on_skill_trigger(skill_name, "cast")
func on_attack_hit_trigger(skill_name: String, trigger_name: String) -> void:
func on_skill_trigger(skill_name: String, trigger_name: String) -> void:
var func_name: String = "on_%s_%s" % [skill_name, trigger_name]
if has_method(func_name):
call(func_name)
func on_skill_release_trigger(skill_name: String) -> void:
var func_name: String = "on_%s_release" % skill_name
if has_method(func_name):
call(func_name)
#====skill_trigger====
func on_hero01_long_stab01_cast():
if status.skill_repeat_count >= 5:
skill.cast_skill_by_name("hero01_long_stab02", status.move_dir)
func on_hero01_fist_skill01_break():

@ -0,0 +1,57 @@
extends Area3D
class_name BattleAttackArea
@onready var battle: Battle = (%Battle as Battle)
@onready var collision: CollisionShape3D = (%BattleAttackAreaCollision as CollisionShape3D)
var is_active: bool
var alive_time: float
var attack_info: Struct.AttackInfo
var attack_id_set: Dictionary = {}
func _ready():
body_entered.connect(on_body_entered)
func _process(delta: float) -> void:
if is_active:
alive_time -= delta
if alive_time <= 0:
set_active(false)
func refresh_attack_area(attack_info_new: Struct.AttackInfo) -> void:
attack_info = attack_info_new
var offset_xz: Vector2 = attack_info.attack_dir * attack_info.attack_box.offset.x
var offset_y: float = attack_info.attack_box.offset.y
var offset: Vector3 = Vector3(offset_xz.x, offset_y, offset_xz.y)
var shape: Shape3D = attack_info.attack_box.shape
collision.position = offset
collision.shape = shape
attack_id_set.clear()
alive_time = Setting.animation_frame_rate
set_active(false)
set_active(true)
func on_body_entered(body: Node3D):
call_deferred("on_body_entereddeferred", body)
func on_body_entereddeferred(body: Node3D):
if body is Character:
if not attack_id_set.has(body.id):
battle.on_attack_character(body, attack_info)
attack_id_set[body.id] = true
func set_active(value: bool) -> void:
if value:
alive_time = Setting.animation_frame_rate
else:
alive_time = 0
is_active = value
collision.disabled = not value

@ -236,9 +236,9 @@ func get_character_owner() -> Character:
return self
func attack1() -> bool:
return battle.character_attack1()
func attack1() -> void:
battle.character_attack1()
func attack2() -> bool:
return battle.character_attack2()
func attack2() -> void:
battle.character_attack2()

@ -131,10 +131,14 @@ func update_move_check(delta) -> bool:
if normal_speed < -6 and normal.y >= 0:
#墙体互动
Global.effect_mgr.cast_particle(ResourceManager.particle_hit_ground_heavy, character.pos(), normal)
var velocity_new: Vector3 = velocity - normal * normal_speed * 2
var attack_dir: Vector2 = Vector2(velocity_new.x, velocity_new.z).normalized()
var velocity_new: Vector3 = velocity - normal * normal_speed * 2
var attack_dir: Vector2 = Vector2(velocity_new.x, velocity_new.z).normalized()
character.velocity = Vector3.ZERO
battle.add_attack(ResourceManager.cfg_attack_rebound, ResourceManager.cfg_attack_box_rebound, true, attack_dir)
var attack_info: Struct.AttackInfo = Struct.AttackInfo.new()
attack_info.attack = ResourceManager.cfg_attack_rebound
attack_info.attack_box = ResourceManager.cfg_attack_box_rebound
attack_info.attack_dir = attack_dir
battle.add_attack(attack_info)
elif normal_speed <-3:
#反弹
Global.effect_mgr.cast_particle(ResourceManager.particle_hit_ground_normal, character.pos(), normal)

@ -51,7 +51,7 @@ func update_charging() -> void:
if not input.action == release_key:
continue
refresh_input(i)
battle.on_skill_release_trigger(status.skill_cfg.get_res_name())
battle.on_skill_release(status.skill_cfg.get_res_name())
break

@ -7,6 +7,8 @@ class_name Skill
@onready var effect: Effect = (%Effect as Effect)
@onready var buff: Buff = (%Buff as Buff)
@onready var move: Move = (%Move as Move)
@onready var battle: Battle = (%Battle as Battle)
@onready var battle_attack_area: BattleAttackArea = (%BattleAttackArea as BattleAttackArea)
var skill_dict: Dictionary = {} #name -> skill
var skill_map: Dictionary = {} #input -> skillCfg[]
@ -91,8 +93,8 @@ func cast_skill_mp_cost(cfg: SkillCfg) -> bool:
return true
func cast_skill_by_name(name: String, cast_dir: Vector2):
var cfg: SkillCfg = skill_dict.get(name)
func cast_skill_by_name(skill_name: String, cast_dir: Vector2) -> void:
var cfg: SkillCfg = skill_dict.get(skill_name)
if not cfg:
return
if not cast_skill_mp_cost(cfg):
@ -118,13 +120,19 @@ func cast_skill(cfg: SkillCfg, cast_dir: Vector2, action_key: String = ""):
if cfg.is_lock_x_move:
skill_move_dir = cast_dir
#技能重复次数
if status.skill_cfg and status.skill_cfg == cfg:
status.skill_repeat_count += 1
else:
status.skill_repeat_count = 0
break_skill()
status.speed_up_rate = -1
status.is_free_control = false
status.is_free_turn = false
status.is_skill_running = true
status.skill_cfg = cfg
status.skill_dir = cast_dir
status.skill_dir = cast_dir.normalized()
status.skill_move_dir = skill_move_dir
status.break_level = Enum.EBreakLevel.None
status.stance = cfg.stance_to
@ -148,6 +156,8 @@ func cast_skill(cfg: SkillCfg, cast_dir: Vector2, action_key: String = ""):
play(animation_name, -1, Setting.animation_speed_scale)
seek(0, true, true)
battle.on_skill_cast(cfg.get_res_name())
func break_skill():
stop()
@ -167,6 +177,7 @@ func break_skill():
status.skill_action_key = ""
status.set_skill_break_level_add(0)
buff.remove_buff("charging")
battle_attack_area.set_active(false)
if status.throw_target != 0:
var character_to: Character = Global.character_mgr.get_character(status.throw_target)
if character_to:
@ -181,12 +192,6 @@ func cancel_skill():
view.reset()
func on_attack_miss():
# 攻击未命中时跳帧
_frame_forward()
status.set_skill_break_level_add(-1)#todo
func on_hold() -> void:
_frame_back(1)

@ -12,6 +12,7 @@ class BulletOrder:
var cast_dir: Vector2
var target: int
#实体属性
var id: int #id
var owner_id: int #所有者id
@ -80,13 +81,12 @@ var skill_cfg: SkillCfg #当前技能
var is_skill_running: bool #技能是否正在释放
var skill_dir: Vector2 #技能释放方向
var skill_move_dir: Vector2 #技能位移方向
var skill_action_key: String #技能输入指令
var skill_repeat_count: int #技能重复释放次数
@export var skill_move_speed: float #技能位移速度
@export var skill_float_speed: float #技能y位移速度
@export var skill_move_stop: bool #技能位移速度是否停止生效
var skill_action_key: String #技能输入指令
@export var skill_break_level_add: int #技能额外打断等级
#核心状态

@ -5,3 +5,4 @@ class_name AttackBoxCfg
@export var offset: Vector2 #偏移
@export var is_throw: bool #是否投技(只命中投技目标)
@export var is_direct: bool #是否直接命中
@export var is_hit_self: bool #是否命中自己

@ -4,27 +4,28 @@ class_name CharacterCfg
#基本信息
@export var name: String
@export var type: Enum.ECharacterType
#动画
@export_group("动画")
@export var sprite_frames: SpriteFrames
@export var sprite_height: int
@export var sprite_width: int
#基本组件
@export_group("组件")
@export var move: CharacterMoveCfg
@export var shield: ShieldCfg
@export var stun: StunCfg
@export var mp: MpCfg
@export var ai: AICfg
#战斗信息
@export var ai_behavior_tree: PackedScene
@export_group("战斗数值")
@export var hp_max: float
@export var attack: float
#自带技能参数
@export_group("自带技能参数")
@export var attack1: AttackCfg
@export var attack1_box: AttackBoxCfg
@export var attack2: AttackCfg
@export var attack2_box: AttackBoxCfg
@export var sub_character: CharacterCfg
@export var sub_character_auto_create: bool
#材质
@export_group("受击材质")
@export var material_on: Enum.EMaterial = Enum.EMaterial.None #有护盾时材质
@export var material_off: Enum.EMaterial = Enum.EMaterial.None #无护盾时材质
@ -52,6 +53,8 @@ func get_particle()->Resource:
func get_ai()->PackedScene:
if ai_behavior_tree:
return ai_behavior_tree
var res_name: String = get_res_name()
var path_default: String = "res://scene/ai/%s.tscn" % res_name
if ResourceLoader.exists(path_default):

@ -15,11 +15,9 @@ var refresh_animation: Callable = check_animation
@export_group("攻击参数")
@export var attack1: AttackCfg
@export var attack1_box: AttackBoxCfg
@export var attack1_with_pause_frame: bool
@export var attack1_with_stop: bool
@export var attack2: AttackCfg
@export var attack2_box: AttackBoxCfg
@export var attack2_with_pause_frame: bool
@export var attack2_with_stop: bool
@export_group("数值和标记")
@export var mp_cost: int

@ -24,10 +24,6 @@ extends Node3D
print("done.")
func _process(delta: float) -> void:
pass
func process_mesh_lib(dir_name: String) -> void:
var dir := DirAccess.open(dir_name)
if not dir:

@ -57,4 +57,4 @@ var cfg_character_monster_test4: CharacterCfg = load("res://config/character/mon
var cfg_attack_normal: AttackCfg = load("res://config/attack/sharp_normal_hit.tres") as AttackCfg
var cfg_attack_box_normal: AttackBoxCfg = load("res://config/attack_box/circle_normal.tres") as AttackBoxCfg
var cfg_attack_rebound: AttackCfg = load("res://config/attack/rebound.tres") as AttackCfg
var cfg_attack_box_rebound: AttackBoxCfg = load("res://config/attack_box/circle_normal.tres") as AttackBoxCfg
var cfg_attack_box_rebound: AttackBoxCfg = load("res://config/attack_box/rebound.tres") as AttackBoxCfg

Loading…
Cancel
Save