How to determine where a player clicked a SurfaceGui?

  1. What do you want to achieve? I am attempting to create a nice mouse clicking effect for when you interact with a button. I currently have one for ScreenGuis but I cant figure out how to go about doing the same effect for SurfaceGuis.

  2. What is the issue? I don’t know how to go about finding the position of a players click on a SurfaceGui.

  3. What solutions have you tried so far? I did look for solution out on the web but I couldn’t find any.

Heres the code I have for determining mouse click on a ScreenGui, I am attempting to “port” it over to SurfaceGui input as well. I just have to figure out how to get the position of the click. With a ScreenGui I just used Mouse position - AbsolutePosition.

		local LongestSide = GuiObject.AbsoluteSize.X
		if LongestSide < GuiObject.AbsoluteSize.Y then
			LongestSide = GuiObject.AbsoluteSize.Y
		end
		
		local MouseClickFrame = PlayerGui.MouseClickFrame:Clone()
		MouseClickFrame.Parent = GuiObject.HolderFrame
		MouseClickFrame.Position = UDim2.new(0, Mouse.X - GuiObject.AbsolutePosition.X, 0, Mouse.Y - GuiObject.AbsolutePosition.Y)
		MouseClickFrame:TweenSize(UDim2.new(0, LongestSide * 2, 0, LongestSide * 2), "InOut", "Linear", .3, true)
		TweenService:Create(MouseClickFrame, TweenInfo.new(.3), {BackgroundTransparency = 1}):Play()
		Debris:AddItem(MouseClickFrame, .3)

Thanks and have a good one! If you have any questions let me know!

4 Likes

I don’t think this is possible. Like the game cannot detect a player’s actions on what they do. Its kind of impossible for a game to do that. Im not sure if you can technically do that advantage for the point of it.

I think this helps you

Have you considered using the Adornee property of SurfaceGuis? However a downside is that the Gui would have to be local to the client

Its possible if the SurfaceGui is parented to PlayerGui. When its parented to PlayerGui it can receive input.

That post is for ScreenGuis. I am attempting the same thing with SurfaceGuis.

I figured out a solution, with some help from the Roblox Discord.

The best way and only way I can think of going about this is to cast a Ray from the camera to the mouse position on click. Get the position of the Ray.Hit relative to the hit part. Use CanvasSize to detemine where on the UI it was clicked and go from there.

Heres the code I came up with.

		local GuiParentPart = GuiObject.Parent.Parent.Adornee
		local TopLeftCFrame = GuiParentPart.CFrame * CFrame.new(GuiParentPart.Size.X / 2, GuiParentPart.Size.Y / 2, GuiParentPart.Size.Z / 2)
		local MouseDistanceFromTopLeft = TopLeftCFrame.Position - Mouse.Hit.Position
		local RelativeLocation = Vector2.new(math.abs(MouseDistanceFromTopLeft.X) * GuiObject.Parent.Parent.PixelsPerStud, math.abs(MouseDistanceFromTopLeft.Y) * GuiObject.Parent.Parent.PixelsPerStud)
		
		local MouseClickFrame = PlayerGui.MouseClickFrame:Clone()
		MouseClickFrame.Parent = GuiObject.Parent
		MouseClickFrame.Position = UDim2.new(0, RelativeLocation.X, 0, RelativeLocation.Y)
8 Likes