extends Interactable class_name Button3D signal pressed(button: Button3D) signal held(button: Button3D) signal released(button: Button3D) @export var pressDepth: float = 0.05 @export var pressSpeed: float = 10.0 @export var autoReset: bool = true @export var buttonMesh: MeshInstance3D @export var holdMode: bool = false @export var pressArea: Area3D var isPressed: bool = false var offset: float = 0.0 var pressing_body: Node3D = null func _ready() -> void: if pressArea: pressArea.monitoring = true pressArea.monitorable = true func beginInteract(player, hitPosition: Vector3): if holdMode: isPressed = true offset = pressDepth emit_signal("pressed", self) else: if isPressed: return isPressed = true offset = pressDepth emit_signal("pressed", self) func updateInteract(player): if holdMode and isPressed: emit_signal("held", self) func endInteract(player): if holdMode: isPressed = false offset = 0.0 emit_signal("released", self) else: if autoReset: offset = 0.0 func _physics_process(delta): var target = offset var current = buttonMesh.position.z var newZ = lerp(current, -target, delta * pressSpeed) buttonMesh.position.z = newZ if autoReset and isPressed and abs(newZ) < 0.001: isPressed = false #func _physics_process(delta): ## Detect rigidbody overlap #var bodies = pressArea.get_overlapping_bodies() # #if bodies.size() > 0: #var body = bodies[0] # #if pressing_body == null: #pressing_body = body #isPressed = true #offset = pressDepth #emit_signal("pressed", self) #else: #if holdMode: #emit_signal("held", self) #else: #if pressing_body != null: #pressing_body = null #if autoReset: #offset = 0.0 #isPressed = false #emit_signal("released", self) # ## Animate button #var target = offset #var current = buttonMesh.position.z #var newZ = lerp(current, -target, delta * pressSpeed) #buttonMesh.position.z = newZ # #if autoReset and isPressed and abs(newZ) < 0.001: #isPressed = false