Making a SurfaceGui Frame follow the mouse

I’m currently trying to make a SurfaceGui follow the player’s cursor. I have surfed the internet for an answer to this but nothing seems to help.

So in detail, I have a character in-game which a player can move with their mouse. I need an arrow pointing to the player’s cursor so they can see where that character is going. Here is a picture so you can understand what I mean.

This is the explorer heirarchy. DirectionArrow is a small, hidden frame in the middle of the Gui which allows me to rotate the arrow on an axis.


I am not necessarily asking for a script here, I just need to know what to do to achieve this. Thanks :slight_smile:


I would go about this by thinking about it as a simple placement or object movement script. Get the player’s mouse (raycasting or mouse position) and then determine where it is in correlation with the surface of your map.


I would use mouse.Hit.Position along with CFrame.lookAt for a simple approach that will work well.


I don’t recommend Mouse as it is a legacy object and will soon be considered deprecated in favor of UserInputService / ContextActionService.


This will create a CFrame pointed at the Mouse without vertical movement:

local BasePosition =, 10, 0) --wherever the ring is (change this)
local LookAt = CFrame.lookAt(BasePosition, game:GetService("Players").LocalPlayer:GetMouse().Hit.Position)
RingPartThingy.CFrame = * CFrame.Angles(0, math.atan2(-LookAt.LookVector.X, -LookAt.LookVector.Z), 0)

I’m fairly sure if you use UserInputService you will need to project the MousePosition and use a raycast, which is more complicated than using mouse.Hit, but I get your concerns.


Yes, UIS and CAS are considered by Roblox to be “better”, however the Mouse will remain supported for the time being and as @Katrist just mentioned, using the Mouse is overall simpler and makes more sense to use in this scenario.


I agree with you on that part. It’s overcomplicates alotttttt of things and personally I’m not a fan of it. I guess what I’m trying to say is, if the poster is going to use Mouse, he should proceed with caution and not be surprised if Roblox randomly deprecates it one day.


Something being widely used has never really stopped Roblox in the past though tbh.

Again, I’m just saying that if he uses mouse, then he shouldn’t be surprised if his script breaks one day.

1 Like

I believe I worded my question incorrectly. I want the arrow to change its rotation and point to where the direction of the player’s cursor is. How would I find the direction of where the mouse is and change a GuiObject’s rotation based on that?

1 Like

I believe GuiObject’s don’t have a CFrame property, correct me if I’m wrong

1 Like

Talking about the main part that holds the surface gui.

1 Like

Oh okay, I’ll try it and I will let you know if it works.

1 Like

It seems to kind of work, but when I point the mouse to the middle it freaks out and starts pointing up. How do I prevent it from doing that?

Heres the code:

local mouse = game.Players.LocalPlayer:GetMouse()

	local part = workspace.PlayerTemplate.GuiPart
	part.CFrame = CFrame.lookAt(part.Position, mouse.Hit.Position)

1 Like

It’s because the Y value isn’t the same as that part’s Y value, so it increases the Y position to match. You can fix this by setting the returned position’s Y value to the part’s Y value.


local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local mouse = Players.LocalPlayer:GetMouse()
local part = workspace.PlayerTemplate.GuiPart

	local mousePosition = mouse.Hit.Position
	part.CFrame = CFrame.lookAt(part.Position,, part.Position.Y, mousePosition.Z))

Thanks a lot for your help. I was stuck on this issue for a long time but now it’s fixed.
Again thank you!


No problem, have a good day!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.