Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How i can make button that work repeatedly while it's pressed

Discussion in 'UI Toolkit' started by Loud_Lasagna, Dec 14, 2019.

  1. Loud_Lasagna

    Loud_Lasagna

    Joined:
    Oct 24, 2019
    Posts:
    26
    I need to make a button that will work repeatedly while it is pressed. I did something with the event trigger on this button, and the action repeats endlessly after being pressed
     
    Last edited: Dec 14, 2019
  2. Wobbers

    Wobbers

    Joined:
    Dec 31, 2017
    Posts:
    55
    I guess something like this should work:
    Code (CSharp):
    1. bool mouseDown = false;
    2. button.RegisterCallback<MouseDownEvent>((evt) => mouseDown = true);
    3. button.RegisterCallback<MouseUpEvent>((evt) => mouseDown = false);
    4. button.RegisterCallback<MouseLeaveEvent>((evt) => mouseDown = false);
    and then do the logic in Update/OnUpdate
    Code (CSharp):
    1. void Update()
    2. {
    3.     if(mouseDown)
    4.     {
    5.         ...
    6.     }
    7. }
     
  3. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    486
  4. Loud_Lasagna

    Loud_Lasagna

    Joined:
    Oct 24, 2019
    Posts:
    26
  5. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    I don't think this will work... from my testing, MouseLeaveEvent and MouseUpEvent will work, but MouseDownEvent will never get called. I think this is because the button soaks up the mouse down and doesn't pass it on. I don't know how to get buttons to pass on MouseDownEvent. Maybe you could make your own custom button type that can pass on MouseUpEvent, or you could use a Label instead of a button? The best solution would be if Button had a switch or something that you could set to make the button pass on MouseDownEvent, but I don't know of one.
     
  6. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    Button was made before we had ClickEvent, so it uses a Clickable Manipulator which is a object that attaches itself to a VisualElement and handles a specific set of Events using an internal state machine. This is how the Button enforces that you have to mouse down AND mouse up on the same Button in order to activate it. You can't mouse down somewhere else, move to be on top of the Button, and then mouse up to activate it.

    The problem here is that this Clickable Manipulator will "capture" the mouse as soon as it detects a MouseDown and from this point forward, all mouse events will be sent to this Button and no other element, regardless of where the mouse pointer is on top of. This includes your MouseUp event. That's why the Button eats all mouse events until the Clickable Manipulator is disengaged (receives MouseUp).

    The workaround depends highly on your situation and requirements. Here are some options:
    1. make your own button out of a Label, as you suggested, and handle all mouse events and :hover/:active styles (can just assign the same `.unity-button` class to magically get all the same styles as Button)
    2. put an element on top of your button that captures all events and only lets Button have a subset of events, though note that once the Clickable manipulator is engaged, you will stop getting Mouse events even on the element on top
    3. assign your own custom Clickable manipulator to your Button via button.clickable
     
    lclemens likes this.
  7. Digital_Mimesis_Lab

    Digital_Mimesis_Lab

    Joined:
    Mar 9, 2022
    Posts:
    24