|
|
|
@ -20,14 +20,50 @@ var is_active: bool = false |
|
|
|
var _hits_this_attack: Array[Node] = [] |
|
|
|
var _hits_this_attack: Array[Node] = [] |
|
|
|
## Shape for queries (extracted from child CollisionShape3D) |
|
|
|
## Shape for queries (extracted from child CollisionShape3D) |
|
|
|
var _query_shape: Shape3D = null |
|
|
|
var _query_shape: Shape3D = null |
|
|
|
|
|
|
|
## Debug mesh for visualization |
|
|
|
|
|
|
|
var _debug_mesh: MeshInstance3D = null |
|
|
|
|
|
|
|
var _debug_material: StandardMaterial3D = null |
|
|
|
|
|
|
|
|
|
|
|
func _ready(): |
|
|
|
func _ready(): |
|
|
|
# Find the collision shape for queries |
|
|
|
# Find the collision shape for queries |
|
|
|
for child in get_children(): |
|
|
|
for child in get_children(): |
|
|
|
if child is CollisionShape3D and child.shape: |
|
|
|
if child is CollisionShape3D and child.shape: |
|
|
|
_query_shape = child.shape |
|
|
|
_query_shape = child.shape |
|
|
|
|
|
|
|
_create_debug_visualization(child) |
|
|
|
break |
|
|
|
break |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _create_debug_visualization(collision_shape: CollisionShape3D): |
|
|
|
|
|
|
|
# Create a semi-transparent red mesh to visualize the hitbox |
|
|
|
|
|
|
|
_debug_mesh = MeshInstance3D.new() |
|
|
|
|
|
|
|
_debug_material = StandardMaterial3D.new() |
|
|
|
|
|
|
|
_debug_material.albedo_color = Color(1.0, 0.0, 0.0, 0.4) # Red, semi-transparent |
|
|
|
|
|
|
|
_debug_material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA |
|
|
|
|
|
|
|
_debug_material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED |
|
|
|
|
|
|
|
_debug_material.cull_mode = BaseMaterial3D.CULL_DISABLED # Visible from both sides |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Create mesh matching the collision shape |
|
|
|
|
|
|
|
var mesh: Mesh = null |
|
|
|
|
|
|
|
if collision_shape.shape is BoxShape3D: |
|
|
|
|
|
|
|
var box_mesh = BoxMesh.new() |
|
|
|
|
|
|
|
box_mesh.size = collision_shape.shape.size |
|
|
|
|
|
|
|
mesh = box_mesh |
|
|
|
|
|
|
|
elif collision_shape.shape is SphereShape3D: |
|
|
|
|
|
|
|
var sphere_mesh = SphereMesh.new() |
|
|
|
|
|
|
|
sphere_mesh.radius = collision_shape.shape.radius |
|
|
|
|
|
|
|
sphere_mesh.height = collision_shape.shape.radius * 2 |
|
|
|
|
|
|
|
mesh = sphere_mesh |
|
|
|
|
|
|
|
elif collision_shape.shape is CapsuleShape3D: |
|
|
|
|
|
|
|
var capsule_mesh = CapsuleMesh.new() |
|
|
|
|
|
|
|
capsule_mesh.radius = collision_shape.shape.radius |
|
|
|
|
|
|
|
capsule_mesh.height = collision_shape.shape.height |
|
|
|
|
|
|
|
mesh = capsule_mesh |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if mesh: |
|
|
|
|
|
|
|
_debug_mesh.mesh = mesh |
|
|
|
|
|
|
|
_debug_mesh.material_override = _debug_material |
|
|
|
|
|
|
|
# Don't set transform - it inherits from parent CollisionShape3D |
|
|
|
|
|
|
|
collision_shape.add_child(_debug_mesh) |
|
|
|
|
|
|
|
|
|
|
|
func _physics_process(_delta): |
|
|
|
func _physics_process(_delta): |
|
|
|
if not is_active: |
|
|
|
if not is_active: |
|
|
|
return |
|
|
|
return |
|
|
|
@ -83,11 +119,17 @@ func _process_hit(hurtbox: HurtBox): |
|
|
|
func activate(): |
|
|
|
func activate(): |
|
|
|
is_active = true |
|
|
|
is_active = true |
|
|
|
_hits_this_attack.clear() |
|
|
|
_hits_this_attack.clear() |
|
|
|
|
|
|
|
# Change to yellow when active |
|
|
|
|
|
|
|
if _debug_material: |
|
|
|
|
|
|
|
_debug_material.albedo_color = Color(1.0, 1.0, 0.0, 0.5) # Yellow, semi-transparent |
|
|
|
|
|
|
|
|
|
|
|
## Deactivate hitbox (call when attack ends) |
|
|
|
## Deactivate hitbox (call when attack ends) |
|
|
|
func deactivate(): |
|
|
|
func deactivate(): |
|
|
|
is_active = false |
|
|
|
is_active = false |
|
|
|
_hits_this_attack.clear() |
|
|
|
_hits_this_attack.clear() |
|
|
|
|
|
|
|
# Change back to red when inactive |
|
|
|
|
|
|
|
if _debug_material: |
|
|
|
|
|
|
|
_debug_material.albedo_color = Color(1.0, 0.0, 0.0, 0.4) # Red, semi-transparent |
|
|
|
|
|
|
|
|
|
|
|
## Set damage stats (usually from weapon data) |
|
|
|
## Set damage stats (usually from weapon data) |
|
|
|
func set_stats(new_damage: float, new_knockback: float): |
|
|
|
func set_stats(new_damage: float, new_knockback: float): |
|
|
|
|