How do I tell if a player is touching a gui when dealing with contextactionservice?

When binding a function to context action service, it doesn’t give you a argument to let you know if it was a gui being clicked. How do I tell if the player was touching a gui?

1 Like

You can listen for InputBegan of UserInputService instead, since the second argument the listener gets is if the input was due to interaction with interface (typing in a text box or clicking a GUI button), and check that the input type was a mouse button click

local UserInputService = game:GetService("UserInputService");

UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if (input.UserInputType == Enum.UserInputType.MouseButton1) then
        print(gameProcessed and "Event fired because of interaction with game engine!" or "Didn't interact with game engine");
    end
end);

It depends on why you connected the function with ContextActionService in the first place, you could just connect the function only when inside the gui so that you can eliminate the possibility of needing to consider where the mouse object has to be, all through events like GuiObject.MouseEnter and GuiObject.MouseLeave.

Gui.MouseEnter:Connect(function()
	ContextActionService:BindAction("HoverFunction",
		--[[function here]],
		false, 
		Enum.UserInputType.MouseButton1
	)
end)

Gui.MouseLeave:Connect(function()
	ContextActionService:UnbindAction("HoverFunction")
end)

This can also act as a way to block subsequent bindings to MouseButton1, which may be helpful in your case, who knows.
I would much rather prefer this solution over my alternate one below, just because it’s cleaner and less intensive overall.
Otherwise, the simplest solution I can give is connecting a function to Enum.UserInputType.MouseMovement, and checking from your specified gui if input.Position - gui.AbsolutePosition is within the bounds of gui.AbsoluteSize, maybe something like this:

local gui = --the gui you want to check
local isTouchingGui = false
ContextActionService:BindAction("HoverFunction",function(_,state,input)
	if input.UserInputType == Enum.UserInputType.MouseMovement then
		local dist = input.Position - gui.AbsolutePosition
		local size = gui.AbsoluteSize
		local anchor = gui.AnchorPoint
		if
			dist.X >= size.X*(1-anchor.X) and dist.X <= size.X*anchor.X and
			dist.Y >= size.Y*(1-anchor.Y) and dist.Y <= size.Y*anchor.Y
		then
			isTouchingGui = true
		else
			isTouchingGui = false
		end
		return Enum.ContextActionResult.Pass
	elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
		if state == Enum.UserInputState.Begin and isTouchingGui then
			-- do stuff
		end
	end
end, false, Enum.UserInputType.MouseMovement, Enum.UserInputType.MouseButton1)
1 Like