Hello! I understand that if I don't want my functions triggered when I click on a GUI element and not the game world, I should use _UnhandledInput instead of _Input. I also understand that if I want my function to be triggered repeatedly, I should put it in _Process which runs every frame instead of _UnhandledInput which only runs once per input. So... how can I achieve both?

In _Process my character moves towards the mouse when I hold the mouse button down, but it also moves when I click on a button.
In _UnhandledInput my character will only move if I'm smashing the mouse button.

I'm guessing I could add some global variable that I'd set in _Input and then check it in _PhysicsProcess, but is there a better way to do this?

  • xyz replied to this.
  • housatic Use a flag variable that stores the state of the button:

    var button_down = false
    	
    func _unhandled_input(event):
    	if event is InputEventMouseButton: 
    		if event.is_pressed():
    			button_down = true
    		else:
    			button_down = false
    		
    func _process(delta):
    	if button_down:
    		print("BUTTON IS DOWN")
    housatic changed the title to Run function when mouse is held down, but not when clicking on GUI elements .

    So, this seems to get the job done:

    public override void _Input(InputEvent _event)
    	{
    		if (_event is InputEventMouseButton)
    		{
    			movementAllowed = false;
    		}
    	} 
    
    public override void _UnhandledInput(InputEvent _event)
    {
    	if (_event is InputEventMouseButton)
    		{
    			movementAllowed = true;
    		}
    }
    public override void _Process(double delta)
    {
    	if (movementAllowed)
    	{
    		playerMove(...);
    	}
    }

    But if anyone has a nicer solution, let me know :-)

    housatic Use a flag variable that stores the state of the button:

    var button_down = false
    	
    func _unhandled_input(event):
    	if event is InputEventMouseButton: 
    		if event.is_pressed():
    			button_down = true
    		else:
    			button_down = false
    		
    func _process(delta):
    	if button_down:
    		print("BUTTON IS DOWN")

      I think there are some edge cases to consider for what the best approach is.

      1. If the user clicks on the UI, but then drags over the game world, what would you like to happen?
      2. If the user clicks on the gameworld, but then drags over the UI, what would you like to happen?

      @xyz I'm surprised that mouse release filters through the UI while mouse press doesn't. Do you know if Controls only consume certain mouse events?

        award In this case I don't want dragging from world to UI to trigger the UI, and the other way around, and the solutions above seem to do that :-)