Disable Left-Click Punch on Gui Elements

I have bound left-click mouse to a punch but of course, when the player clicks GUI buttons, they also punch. I have tried to disable this behavior by detecting if the mouse enters or leaves buttons in the GUI and setting a bool that i check when the player clicks to punch.

But the MouseEnter and MouseLeave events are firing even on GUI elements that are not visible, such as in the center of the screen where there are various windows. This is happening because when i turn off a window, I turn off Visibility of the main containing frame and not every single elements inside of it, hence the MouseEnter and MouseLeave still fire.

How are people solving this issue? I really wish I could reliably chekc if the player is hovering over a button that is actually clickable. An invisible button cannot be clicked, even when its visibility is controlled by its parent instance. This state of clickability cannot be checked though, or can it?

1 Like

cant you try making it so if they press the button/gui again it stops?
or every time they press it it punches/does a couple of hits? (or re-upload the animation with it set to loop?)

umm no thats not the issue. I want it where if the player presses any active and visible button on the GUI, to NOT punch. It has nothing to do with the animation.

so do you mean you want it so when they push the button it makes the gui dissapear?

no not all. please read the OP

Well you are on the right step with using MouseEnter and MouseLeave, if you don’t want it to work on invisible/inactive objects, can’t you just do a condition where if the gui is invisible, don’t set the bool?

Example

Frame.MouseEnter:Connect(function()
    if not Frame.Visible then return end --If frame is invisible do nothing
    bool = false
end)

Frame.MouseLeave:Connect(function()
    if not Frame.Visible then return end --If frame is invisible do nothing
    bool = true
end)

I think this is how you want it from the looks of it, since MouseEnter and MouseLeave is a step i nthe right direction, you just need checks before setting anything

Edit: I think I may’ve read the post wrong, I think what you could do is instead of checking the Visibility of the frame that is hovered on, check the visiblity of its main parent since you said you just make the main frame invisible rather than each frame

I tried that! The issue is that GUIs are a deeply nested set of instances and we dont set EVERY instance Visibility property, we just set the top level parent

For example, lets say I have an Inventory Window that opens in the middle of the screen with a variety of buttons that the player can use. Now lets say the player closes this window. The easy way, and they way I do it now, is to set the Top level frame for hat windows to Visible = false. This makes every other instance under it non-visible, but leaves the actual instances Visible property the same as it was.

Iterating through a table of every elements to make it visible and not visible would be taxing to the client. Its also not practical but sometimes instance are meant to be invisible, so you cant just set a blanket

So therefore, the events are still firing!

Did you filter out the GameProccessed boolean? What service are you using for input detection?

1 Like

so for the Gui buttons I am using MouseButton1Clicked event

and for the punch here is my code

UserInputService.InputBegan:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.MouseButton1 then
            if not Knit.Controllers.GuiController.ButtonHover then
                InputController:SendToPowersService({InputId = "Mouse1", KeyState = "InputBegan"})
            end
        end
    end)
UserInputService.InputBegan:Connect(function(input, gp)
        if gp then return end -- this detects if a player is pressing a button or typing in something

        if input.UserInputType == Enum.UserInputType.MouseButton1 then
            if not Knit.Controllers.GuiController.ButtonHover then
                InputController:SendToPowersService({InputId = "Mouse1", KeyState = "InputBegan"})
            end
        end
    end)
3 Likes

Try to use

UserInputService.InputBegan:Connect(function(input,Processed)
        if Processed then return end
        if input.UserInputType == Enum.UserInputType.MouseButton1 then
            if not Knit.Controllers.GuiController.ButtonHover then
                InputController:SendToPowersService({InputId = "Mouse1", KeyState = "InputBegan"})
            end
        end
    end)

The 2nd parameter of InputBegan is gameProcessedEvent, it detects if the game internally detected the event you did, such as when you click on a button. If it’s true, then the game detected it, so we don’t want to activate the punching

Edit: @HugeCoolboy2007 Beat me to it so excuse the double answer

2 Likes

You are BOTH lifesavers! I marked the first as solution but thanks to all of you who tried to help. This worked perfectly! YAY!!!

Glad everything worked out at the end even if at first the solution wasn’t discovered until a fresh pair of eyes came to help. If you have anymore problems don’t be afraid to make another post!