攻击判定系统重构

master
chendian 2 years ago
parent 5045b00225
commit 198a414342

@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=3 format=3 uid="uid://bnfnjdw0tms3h"]
[ext_resource type="Script" path="res://script/config/attack_box_cfg.gd" id="1_661yg"]
[sub_resource type="BoxShape3D" id="BoxShape3D_87jhu"]
[resource]
script = ExtResource("1_661yg")
shape = SubResource("BoxShape3D_87jhu")
offset = Vector2(0.5, 0.5)

@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=3 format=3 uid="uid://diedb7vw7eyxp"]
[ext_resource type="Script" path="res://script/config/attack_box_cfg.gd" id="1_hxvsy"]
[sub_resource type="BoxShape3D" id="BoxShape3D_87jhu"]
size = Vector3(1.6, 1.2, 1.2)
[resource]
script = ExtResource("1_hxvsy")
shape = SubResource("BoxShape3D_87jhu")
offset = Vector2(0.8, 0.6)

@ -1,10 +1,10 @@
[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=2 format=3 uid="uid://bqejjllfy03h3"]
[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=3 format=3 uid="uid://bqejjllfy03h3"]
[ext_resource type="Script" path="res://script/config/attack_box_cfg.gd" id="1_d4mqn"]
[sub_resource type="BoxShape3D" id="BoxShape3D_87jhu"]
[resource]
script = ExtResource("1_d4mqn")
height = 1.0
radius = 0.0
size = Vector2(1, 1)
offset = Vector2(0.5, 0)
shape = SubResource("BoxShape3D_87jhu")
offset = Vector2(0.5, 0.5)

@ -1,10 +1,11 @@
[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=2 format=3 uid="uid://57sukcw6ewqo"]
[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=3 format=3 uid="uid://57sukcw6ewqo"]
[ext_resource type="Script" path="res://script/config/attack_box_cfg.gd" id="1_8rhve"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_pmh6g"]
height = 1.0
[resource]
script = ExtResource("1_8rhve")
height = 1.0
radius = 0.5
size = Vector2(0, 0)
shape = SubResource("CylinderShape3D_pmh6g")
offset = Vector2(0, 0)

@ -1,7 +1,8 @@
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=6 format=3 uid="uid://dkxgra6y2u30l"]
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=7 format=3 uid="uid://dkxgra6y2u30l"]
[ext_resource type="Resource" uid="uid://dib6g7t6p5ac2" path="res://config/attack/blunt_normal_hit.tres" id="1_nott2"]
[ext_resource type="Script" path="res://script/config/player_skill_cfg.gd" id="2_mje6b"]
[ext_resource type="Resource" uid="uid://57sukcw6ewqo" path="res://config/attack_box/circle_normal.tres" id="2_nvq3h"]
[ext_resource type="Animation" uid="uid://dxgqn5fa7aokj" path="res://resource/skill_animation/hero01_fist_air_skill01.tres" id="3_q461t"]
[ext_resource type="SpriteFrames" uid="uid://cajgs8smbkjan" path="res://resource/animation/character/hero01_fist_skill01.aseprite" id="4_seudu"]
[ext_resource type="Resource" uid="uid://c6alg8pmqfdxm" path="res://config/weapon/fist.tres" id="5_70pp4"]
@ -17,6 +18,7 @@ name = ""
skill_animation = ExtResource("3_q461t")
free_lock = false
attack1 = ExtResource("1_nott2")
attack1_box = ExtResource("2_nvq3h")
refresh_animation = false
sprite_frames = ExtResource("4_seudu")
animation_name = "fist_air_skill01"

@ -1,6 +1,7 @@
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=6 format=3 uid="uid://7e4fnj5sg72s"]
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=7 format=3 uid="uid://7e4fnj5sg72s"]
[ext_resource type="Resource" uid="uid://dib6g7t6p5ac2" path="res://config/attack/blunt_normal_hit.tres" id="1_k0cmy"]
[ext_resource type="Resource" uid="uid://bqejjllfy03h3" path="res://config/attack_box/box_normal.tres" id="2_ixt4v"]
[ext_resource type="Script" path="res://script/config/player_skill_cfg.gd" id="2_yc8jq"]
[ext_resource type="Animation" uid="uid://t01a4jvp8srr" path="res://resource/skill_animation/hero01_fist_attack01.tres" id="3_b2pdb"]
[ext_resource type="SpriteFrames" uid="uid://bhsotj76tuovy" path="res://resource/animation/character/hero01_fist_attack.aseprite" id="4_ymqrn"]
@ -17,6 +18,7 @@ name = ""
skill_animation = ExtResource("3_b2pdb")
free_lock = false
attack1 = ExtResource("1_k0cmy")
attack1_box = ExtResource("2_ixt4v")
refresh_animation = false
sprite_frames = ExtResource("4_ymqrn")
animation_name = "fist_attack01"

@ -1,7 +1,8 @@
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=6 format=3 uid="uid://dubkvm86cj32f"]
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=7 format=3 uid="uid://dubkvm86cj32f"]
[ext_resource type="Resource" uid="uid://c87w2x5qfqdns" path="res://config/attack/blunt_normal_hit_back.tres" id="1_ixy7x"]
[ext_resource type="Script" path="res://script/config/player_skill_cfg.gd" id="2_h70wx"]
[ext_resource type="Resource" uid="uid://bqejjllfy03h3" path="res://config/attack_box/box_normal.tres" id="2_saiae"]
[ext_resource type="Animation" uid="uid://cyu0yin1rpiak" path="res://resource/skill_animation/hero01_fist_attack02.tres" id="3_tllt1"]
[ext_resource type="SpriteFrames" uid="uid://bhsotj76tuovy" path="res://resource/animation/character/hero01_fist_attack.aseprite" id="4_fevaa"]
[ext_resource type="Resource" uid="uid://c6alg8pmqfdxm" path="res://config/weapon/fist.tres" id="5_gliie"]
@ -17,6 +18,7 @@ name = ""
skill_animation = ExtResource("3_tllt1")
free_lock = false
attack1 = ExtResource("1_ixy7x")
attack1_box = ExtResource("2_saiae")
refresh_animation = false
sprite_frames = ExtResource("4_fevaa")
animation_name = "fist_attack02"

@ -1,7 +1,8 @@
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=6 format=3 uid="uid://dekpkk8o6o8hk"]
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=7 format=3 uid="uid://dekpkk8o6o8hk"]
[ext_resource type="Resource" uid="uid://duu05cr8gk5v4" path="res://config/attack/blunt_mid_hit_blow.tres" id="1_am4eq"]
[ext_resource type="Script" path="res://script/config/player_skill_cfg.gd" id="2_fde7v"]
[ext_resource type="Resource" uid="uid://diedb7vw7eyxp" path="res://config/attack_box/box_mid.tres" id="2_ja1d4"]
[ext_resource type="Animation" uid="uid://c6mk8tfdpniys" path="res://resource/skill_animation/hero01_fist_attack03.tres" id="3_6rajt"]
[ext_resource type="SpriteFrames" uid="uid://bhsotj76tuovy" path="res://resource/animation/character/hero01_fist_attack.aseprite" id="4_orcy6"]
[ext_resource type="Resource" uid="uid://c6alg8pmqfdxm" path="res://config/weapon/fist.tres" id="5_r5lmk"]
@ -17,6 +18,7 @@ name = ""
skill_animation = ExtResource("3_6rajt")
free_lock = false
attack1 = ExtResource("1_am4eq")
attack1_box = ExtResource("2_ja1d4")
refresh_animation = false
sprite_frames = ExtResource("4_orcy6")
animation_name = "fist_attack03"

@ -1,6 +1,7 @@
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=6 format=3 uid="uid://b4aysymwqtvtd"]
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=7 format=3 uid="uid://b4aysymwqtvtd"]
[ext_resource type="Resource" uid="uid://duu05cr8gk5v4" path="res://config/attack/blunt_mid_hit_blow.tres" id="1_s12sc"]
[ext_resource type="Resource" uid="uid://diedb7vw7eyxp" path="res://config/attack_box/box_mid.tres" id="2_0lps6"]
[ext_resource type="Script" path="res://script/config/player_skill_cfg.gd" id="2_mhuew"]
[ext_resource type="Animation" uid="uid://6u3dhxly760l" path="res://resource/skill_animation/hero01_fist_attack04.tres" id="3_bst70"]
[ext_resource type="SpriteFrames" uid="uid://bhsotj76tuovy" path="res://resource/animation/character/hero01_fist_attack.aseprite" id="4_hyek5"]
@ -17,6 +18,7 @@ name = ""
skill_animation = ExtResource("3_bst70")
free_lock = false
attack1 = ExtResource("1_s12sc")
attack1_box = ExtResource("2_0lps6")
refresh_animation = false
sprite_frames = ExtResource("4_hyek5")
animation_name = "fist_attack04"

@ -1,6 +1,7 @@
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=6 format=3 uid="uid://0n2jnkdrwa2l"]
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=7 format=3 uid="uid://0n2jnkdrwa2l"]
[ext_resource type="Resource" uid="uid://bwe8xlgfhx1gl" path="res://config/attack/blunt_heavy_hit_blow.tres" id="1_5lwhl"]
[ext_resource type="Resource" uid="uid://diedb7vw7eyxp" path="res://config/attack_box/box_mid.tres" id="2_xua7v"]
[ext_resource type="Script" path="res://script/config/player_skill_cfg.gd" id="2_ym7q1"]
[ext_resource type="Animation" uid="uid://b2xdmgnem1h4g" path="res://resource/skill_animation/hero01_fist_attack05.tres" id="3_dbjmb"]
[ext_resource type="SpriteFrames" uid="uid://bhsotj76tuovy" path="res://resource/animation/character/hero01_fist_attack.aseprite" id="4_mhr07"]
@ -17,6 +18,7 @@ name = ""
skill_animation = ExtResource("3_dbjmb")
free_lock = false
attack1 = ExtResource("1_5lwhl")
attack1_box = ExtResource("2_xua7v")
refresh_animation = false
sprite_frames = ExtResource("4_mhr07")
animation_name = "fist_attack05"

@ -1,8 +1,9 @@
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=6 format=3 uid="uid://dkr1k00c2eecc"]
[gd_resource type="Resource" script_class="SkillPlayerCfg" load_steps=7 format=3 uid="uid://dkr1k00c2eecc"]
[ext_resource type="Resource" uid="uid://bsqk3q6mccllg" path="res://config/attack/sharp_normal_hit.tres" id="1_6ven2"]
[ext_resource type="Resource" uid="uid://d3mcp8sf6qbmd" path="res://config/attack/sharp_normal_hit.tres" id="1_6ven2"]
[ext_resource type="Script" path="res://script/config/player_skill_cfg.gd" id="1_gik08"]
[ext_resource type="Animation" uid="uid://daopmieibx3b7" path="res://resource/skill_animation/hero01_long_attack01.tres" id="2_6nbpq"]
[ext_resource type="Resource" uid="uid://bqejjllfy03h3" path="res://config/attack_box/box_normal.tres" id="2_my38a"]
[ext_resource type="Resource" uid="uid://cy3wwalxeyro0" path="res://config/weapon/long.tres" id="4_id85o"]
[ext_resource type="SpriteFrames" uid="uid://ce83cuqwgwwi4" path="res://resource/animation/character/hero01_long_attack.aseprite" id="5_xel5p"]
@ -17,6 +18,7 @@ name = ""
skill_animation = ExtResource("2_6nbpq")
free_lock = false
attack1 = ExtResource("1_6ven2")
attack1_box = ExtResource("2_my38a")
refresh_animation = false
sprite_frames = ExtResource("5_xel5p")
animation_name = "long_attack01"

@ -13,7 +13,7 @@
[ext_resource type="Script" path="res://script/character/buff.gd" id="9_jlnhy"]
[ext_resource type="Script" path="res://script/character/effect.gd" id="12_eyfcd"]
[sub_resource type="BoxShape3D" id="BoxShape3D_ty8lx"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_qajx7"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_3u7mw"]
render_priority = 0
@ -29,13 +29,12 @@ _data = [Vector2(0, 6), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[node name="Character" type="CharacterBody3D"]
collision_layer = 512
collision_layer = 16
script = ExtResource("1_tonbs")
[node name="Collision" type="CollisionShape3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0, 0)
shape = SubResource("BoxShape3D_ty8lx")
shape = SubResource("CylinderShape3D_qajx7")
[node name="Status" type="Node3D" parent="."]
unique_name_in_owner = true

@ -13,7 +13,7 @@
[node name="View" parent="." index="2"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.693056, 0)
sprite_frames = ExtResource("2_7gyv2")
animation = &"long_attack04"
animation = &"long_attack01"
[node name="Combo" type="Node3D" parent="." index="8"]
unique_name_in_owner = true

@ -4,9 +4,7 @@ extends Node3D
func get_resource_name(resource:Resource) -> String:return resource.resource_path.get_file().trim_suffix('.tres') #todo 性能
func snap_vector3(value:Vector3) -> Vector3:return Vector3(snap_float(value.x),snap_float(value.y),snap_float(value.z))
func snap_float(value:float) -> float:return floor(value/Setting.pixel_size) * Setting.pixel_size
func grid_vector3(value:Vector3) -> Vector3:return Vector3(grid_float(value.x),grid_float(value.y),grid_float(value.z))
func grid_vector2(value:Vector2) -> Vector2:return Vector2(grid_float(value.x),grid_float(value.y))
func grid_float(value:float) -> float:return Setting.pixel_size * Setting.grid_pixel_size * value
func dir_angle(dir:Vector2) -> float:dir.x = abs(dir.x);return dir.angle_to(Vector2.RIGHT)
func vector_reduce(vector:Vector2,reduce:float) -> Vector2:
var len = vector.length()
@ -22,39 +20,17 @@ func raycast_wall(from:Vector3,to:Vector3) -> bool:
var result = space_state.intersect_ray(query)
return result.size()>0
func attack_detection(pos:Vector3,target_pos:Vector3,target_radius:float,target_height:float,attack_dir:Vector2,attack_height:float,attack_size:Vector2,attack_radius:float) -> bool:
# 检查Y
var attack_y_min = pos.y
var attack_y_max = pos.y + attack_height
var target_y_min = target_pos.y
var target_y_max = target_pos.y + target_height
if attack_y_min > target_y_max || attack_y_max < target_y_min:
return false
# 保底距离
if pos.distance_to(target_pos) < 0.01:
return true
# 2d距离
var dist_2d = Vector2(pos.x,pos.z).distance_to(Vector2(target_pos.x,target_pos.z))
# 如果是圆形
if attack_radius:
return dist_2d <= attack_radius + target_radius
# 旋转target
var angle = attack_dir.angle_to(Vector2.RIGHT)
target_pos = target_pos - pos
target_pos = target_pos.rotated(Vector3.UP,angle)
var dist_x = abs(target_pos.x) - attack_size.x
var dist_y = abs(target_pos.z) - attack_size.y
if dist_x <= target_radius && dist_y <= target_radius:
if (dist_x <= 0 || dist_y <= 0):
return true
var dist_squared = pow(dist_x, 2) + pow(dist_y, 2)
return dist_squared <= pow(target_radius, 2)
return false
func raycast_character(shape:Shape3D ,origin:Vector3 ,dir:Vector2):
var space_state = get_world_3d().direct_space_state
var query = PhysicsShapeQueryParameters3D.new()
var angle = dir_angle(dir)
query.shape = shape
query.transform.origin = origin
query.transform.basis = query.transform.basis.rotated(Vector3.UP, angle)
var result = space_state.intersect_shape(query)
result = result.map(func(v): return v["collider"])
result = result.filter(func(v): return v is Character)
return result
func refresh_animation_lib():
var animation_library_path = "res://resource/skill_animation_library/animation_library.tres"

@ -23,29 +23,19 @@ func attack2():
var attack_box = status.skill_cfg.get_attack2_box()
call_deferred("_attack",attack,attack_box)
func _attack(attack,attack_box):
if !status.skill_cfg:
return
var enemy_list = Global.character_mgr.get_enemy_list(character.id())
func _attack(attack:AttackCfg,attack_box:AttackBoxCfg):
var pos = character.pos()
var attack_dir = status.skill_dir.normalized()
var attack_height = attack_box.height
var attack_size = Util.grid_vector2(attack_box.size)
var attack_radius = attack_box.radius
var offset_xz = attack_dir * Util.grid_float(attack_box.offset.x)
pos += Vector3(offset_xz.x,Util.grid_float(attack_box.offset.y),offset_xz.y)
var offset_xz = attack_dir * attack_box.offset.x
var offset_y = attack_box.offset.y
pos += Vector3(offset_xz.x,offset_y,offset_xz.y)
var result = Util.raycast_character(attack_box.shape,pos,attack_dir)
var is_stuck = false
for enemy in enemy_list:
var target_pos = enemy.pos()
var target_radius = enemy.radius()
var target_height = enemy.height()
if Util.attack_detection(pos,target_pos,target_radius,target_height,attack_dir,attack_height,attack_size,attack_radius):
var hit_info = HitInfo.new()
hit_info.from = character.id()
hit_info.to = enemy.id()
hit_info.dir = attack_dir
hit_info.attack = attack
is_stuck = is_stuck or settle(hit_info)
for target:Character in result:
if target.team() == character.team():
continue
target.add_attack(character.id(),attack_dir,attack)
is_stuck = true
if !is_stuck and !attack.is_force_pause:
skill.on_attack_miss()

@ -16,7 +16,7 @@ func init(id:int,cfg:CharacterCfg,team:Enum.ETeam):
var half_height = Setting.pixel_size * cfg.sprite_harf_height
var height = half_height * 2
var width = Setting.pixel_size * cfg.sprite_width
var body_scale = Vector3(width,height,width)
var body_scale = Vector3(width,half_height,width)
collision.position = Vector3(0,half_height,0)
collision.scale = body_scale
status.basic_offset = Vector3(0,half_height,0)

@ -86,9 +86,7 @@ func _cast_particle(resource:Resource ,is_attach:bool):
return
var new_particle = resource.instantiate() as Particle
new_particle.name = "particle"
var dir = status.skill_dir as Vector2
dir.x = abs(dir.x)
var angle = dir.angle_to(Vector2.RIGHT)
var angle = Util.dir_angle(status.skill_dir)
new_particle.rotation.y = angle if is_right else -angle
new_particle.scale.x = abs(new_particle.scale.x) * (1 if is_right else -1)
new_particle.position = status.basic_offset

@ -2,7 +2,5 @@ extends Resource
class_name AttackBoxCfg
@export var height : float = 1 #判定框高度
@export var radius : float #圆形判定框 半径
@export var size : Vector2 #矩形判定框 大小
@export var shape : Shape3D
@export var offset : Vector2 #偏移

Loading…
Cancel
Save