class_name XRFirearmTrigger extends Node @export var mesh_trigger : MeshInstance3D @export var value : float @export var handle_grabpoints : Array[XRToolsGrabPoint] @onready var _parent : XRToolsPickable = get_parent() # Current controller holding this object var _current_controller : XRController3D var triggered : bool = false # Add support for is_xr_class on XRTools classes func is_xr_class(name : String) -> bool: return name == "XRFirearmTrigger" # Called when the node enters the scene tree for the first time. func _ready() -> void: # Listen for when this object is picked up or dropped _parent.grabbed.connect(_on_grabbed) _parent.released.connect(_on_released) # disable handle grabpoints on ready for handle_grabpoint in handle_grabpoints: handle_grabpoint.enabled = false func _physics_process(_delta): if is_instance_valid(_parent): # toggle handle grabpoints if parent got grabbed/released if _parent.get_picked_up_by(): for handle_grabpoint in handle_grabpoints: handle_grabpoint.enabled = true else: for handle_grabpoint in handle_grabpoints: handle_grabpoint.enabled = false # Called when this object is grabbed func _on_grabbed(_pickable, _by) -> void: _update_controller_signals() for handle_grabpoint in handle_grabpoints: handle_grabpoint.enabled = true # Called when this object is released func _on_released(_pickable, _by) -> void: # disables handle grabpoints to ensure no missgrab if pickable is not being held for handle_grabpoint in handle_grabpoints: handle_grabpoint.enabled = false _update_controller_signals() # Update the controller signals func _update_controller_signals() -> void: # Find the primary controller holding the firearm var controller := _parent.get_picked_up_by_controller() var grab_point := _parent.get_active_grab_point() as XRToolsGrabPointHand if not grab_point or grab_point.handle != "Grip": controller = null # If the bound controller is no-longer correct then unbind if _current_controller and _current_controller != controller: _current_controller.button_pressed.disconnect(_on_controller_trigger_pressed) _current_controller.button_released.disconnect(_on_controller_trigger_released) if triggered: mesh_trigger.rotate(Vector3(1, 0, 0), value) triggered = false _current_controller = null # If we need to bind to a new controller then bind if controller and not _current_controller: _current_controller = controller _current_controller.button_pressed.connect(_on_controller_trigger_pressed) _current_controller.button_released.connect(_on_controller_trigger_released) # Called when a controller button is released func _on_controller_trigger_released(trigger_button : String): # Skip if not pose-toggle button if trigger_button != "trigger_click": return mesh_trigger.rotate(Vector3(1, 0, 0), value) triggered = false # Called when a controller button is pressed func _on_controller_trigger_pressed(trigger_button : String): # Skip if not pose-toggle button if trigger_button != "trigger_click": return triggered = true mesh_trigger.rotate(Vector3(1, 0, 0), -value)