extends Area3D class_name HurtBox ## A component that receives damage from HitBoxes ## Attach to any entity that can be damaged (players, enemies, destructibles) ## NOTE: This is a passive detection zone - HitBox handles the collision detection ## Global debug visibility toggle (static-like via class name access) static var debug_visible: bool = true ## The entity that owns this hurtbox (should be a BaseUnit or similar) @export var owner_entity: Node = null ## Debug mesh for visualization var _debug_mesh: MeshInstance3D = null var _debug_material: StandardMaterial3D = null var _hit_flash_timer: float = 0.0 const HIT_FLASH_DURATION: float = 0.3 # seconds func _ready(): # Auto-find owner if not set (traverse up to find BaseUnit) if owner_entity == null: var parent = get_parent() while parent: if parent is BaseUnit: owner_entity = parent break parent = parent.get_parent() # Configure collision - hurtboxes are on layer 5, detect nothing (passive) collision_layer = 16 # Layer 5 (hurtbox) collision_mask = 0 # Don't detect anything - hitboxes detect us # Ensure we can be detected but don't detect others monitorable = true monitoring = false # Add debug visualization _create_debug_visualization() func _process(delta): # Update debug visibility if _debug_mesh: _debug_mesh.visible = HurtBox.debug_visible # Handle hit flash timer if _hit_flash_timer > 0.0: _hit_flash_timer -= delta if _hit_flash_timer <= 0.0: # Flash finished, return to green if _debug_material: _debug_material.albedo_color = Color(0.0, 1.0, 0.0, 0.3) # Green func _create_debug_visualization(): # Find the collision shape to visualize for child in get_children(): if child is CollisionShape3D and child.shape: # Create a semi-transparent green mesh to visualize the hurtbox _debug_mesh = MeshInstance3D.new() _debug_material = StandardMaterial3D.new() _debug_material.albedo_color = Color(0.0, 1.0, 0.0, 0.3) # Green, 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 child.shape is BoxShape3D: var box_mesh = BoxMesh.new() box_mesh.size = child.shape.size mesh = box_mesh elif child.shape is SphereShape3D: var sphere_mesh = SphereMesh.new() sphere_mesh.radius = child.shape.radius sphere_mesh.height = child.shape.radius * 2 mesh = sphere_mesh elif child.shape is CapsuleShape3D: var capsule_mesh = CapsuleMesh.new() capsule_mesh.radius = child.shape.radius capsule_mesh.height = child.shape.height mesh = capsule_mesh if mesh: _debug_mesh.mesh = mesh _debug_mesh.material_override = _debug_material _debug_mesh.visible = HurtBox.debug_visible # Don't set transform - it inherits from parent CollisionShape3D child.add_child(_debug_mesh) break ## Call this when the hurtbox is hit to flash red func flash_hit(): _hit_flash_timer = HIT_FLASH_DURATION if _debug_material: _debug_material.albedo_color = Color(1.0, 0.0, 0.0, 0.5) # Red, semi-transparent