extends Area3D class_name Hitbox @export var pushbox_curve: Curve @onready var character: Character = (get_owner() as Character) @onready var status: Status = (%Status as Status) 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 area_entered.connect(_on_area_entered) area_exited.connect(_on_area_exited) func _process(_delta) -> void: var is_skill_running: bool = status.is_skill_running if not is_skill_running: return var speed_dir: Vector2 = status.speed_dir if speed_dir.length() == 0: return var skill_cfg: SkillCfg = status.skill_cfg if not skill_cfg: return if skill_cfg.ignore_push: 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)) status.speed_down_push_rate = speed_down_push_rate return func _on_area_entered(area: Area3D): if area is Hitbox: if area.character.team() != character.team(): pushbox_list.append(area) func _on_area_exited(area: Area3D): if area is Hitbox: if area.character.team() != character.team(): pushbox_list.erase(area)