|
|
|
|
extends Area3D
|
|
|
|
|
class_name Hitbox
|
|
|
|
|
|
|
|
|
|
@export var pushbox_curve: Curve
|
|
|
|
|
|
|
|
|
|
@onready var character: Character = (get_owner() as Character)
|
|
|
|
|
|
|
|
|
|
var radius: float
|
|
|
|
|
var pushbox_list: Array[Hitbox] = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _ready():
|
|
|
|
|
var collisionShape3D: CollisionShape3D = $CollisionShape3D as CollisionShape3D
|
|
|
|
|
var shape: CylinderShape3D = collisionShape3D.shape as CylinderShape3D
|
|
|
|
|
radius = shape.radius * scale.x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _process(delta) -> void:
|
|
|
|
|
var speed_dir: Vector2 = character.get_status("speed_dir") as Vector2
|
|
|
|
|
if speed_dir.length() == 0:
|
|
|
|
|
return
|
|
|
|
|
var is_skill_running: bool = character.get_status("is_skill_running") as bool
|
|
|
|
|
if not is_skill_running:
|
|
|
|
|
character.set_status("speed_down_push_rate", 0)
|
|
|
|
|
return
|
|
|
|
|
var skill_cfg: SkillCfg = character.get_status("skill_cfg") as SkillCfg
|
|
|
|
|
if not skill_cfg:
|
|
|
|
|
return
|
|
|
|
|
if skill_cfg.ignore_push:
|
|
|
|
|
character.set_status("speed_down_push_rate", 0)
|
|
|
|
|
return
|
|
|
|
|
var speed_down_push_rate: float = 0
|
|
|
|
|
var pos: Vector2 = character.pos2D()
|
|
|
|
|
for pushbox: Hitbox in pushbox_list:
|
|
|
|
|
var target_pos: Vector2 = pushbox.character.pos2D()
|
|
|
|
|
var dir: Vector2 = target_pos - pos
|
|
|
|
|
if speed_dir.dot(dir) <= 0:
|
|
|
|
|
continue
|
|
|
|
|
var dist: float = dir.length()
|
|
|
|
|
if dist == 0:
|
|
|
|
|
continue
|
|
|
|
|
var dist_rate = clamp(dist/(radius+pushbox.radius), 0, 1)
|
|
|
|
|
speed_down_push_rate = max(speed_down_push_rate, pushbox_curve.sample(dist_rate))
|
|
|
|
|
character.set_status("speed_down_push_rate", speed_down_push_rate)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func on_area_entered(area: Area3D):
|
|
|
|
|
if area is Hitbox:
|
|
|
|
|
pushbox_list.append(area)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func on_area_exited(area: Area3D):
|
|
|
|
|
if area is Hitbox:
|
|
|
|
|
pushbox_list.erase(area)
|