How do I get a CFrame value from a GUI's position?

I am trying to get the GUI’s position in the workspace, like mouse.Hit but with a text button instead of a mouse.

local gui = script.Parent

function getCFrame()
    return ?????
end)

gui.MouseButton1Click:connect(function()
    local cf = getCFrame()
    if cf then Instance.new("Part", workspace).CFrame = cf end
end)
5 Likes

A Gui will use UDim2 to change position (or get its position) so use that instead of CFrame.

https://developer.roblox.com/api-reference/datatype/UDim2

3 Likes

I want to get the position the gui is pointing at, like mouse.hit

1 Like

Sounds like you would need a raycast but I am not sure how it would be implemented.

1 Like

On the developer hub look up Camera… This has some useful functions. You’re probably looking for ScreenToWorldPoint

You can use ScreenPointToRay and RayCasting to achieve this.

local rayMag1 = main.camera:ScreenPointToRay(X, Y, Depth)
local newRay = Ray.new(rayMag1.Origin, rayMag1.Direction * 100)
local hit, position = workspace:FindPartOnRay(newRay, player.Character)

Use the X,Y parameters of MouseButton1Click to get the X and Y values to plugin:

gui.MouseButton1Click:Connect(function(X, Y)
    print(("Left mouse click at (%s, %s)"):format(X, Y))
end)

Depth can be set to 0.

To convert this into a CFrame, use: CFrame.new(Vector3 pos, Vector 3 lookAt). For example:
CFrame.new(camera.CFrame.lookVector, position)

3 Likes

ScreenToPointRay is what you’ll need to be using. This is a property under camera where you can get the 3D position of your Gui using the datatype UDim2. What you should expect to return is a Ray where you can use to get the position of the of the Gui and then get the CFrame using the information we collect.

Similar principle to how you’d raycast normally just that you have to use other functions to implement into Ray.new().

Step 1: Get the UDim2 (x,y) values of your Gui.
In this case, I’ll use (0.5,0.5). Make sure you’re using AbsolutePosition instead of Position because you can give yourself an inaccurate result. Devices have different sized screens therefore you’ll need to adapt to each of them.

Step 2: Use the function ScreenToPointRay to return a Ray.

Step 3: Using the properties of the Ray you can get the origin and go in the direction from where the (X,Y) values are. You can do this by:

local Raycast = CurrentCamera:ScreenPointToRay(Frame.AbsolutePosition.X, Frame.AbsolutePosition.Y, 0)
local Ray = Ray.new(Raycast.Origin,  Raycast.Direction * 100)

Step 4: Make sure of FindPartOnRayWithIgnoreList. You can collect a list of instances you want to ignore which you can do by CollectionService- using :AddTag() or use a Tag plugin. Remember to put your own character into the ignore list (Player.Character)

Step 5: Use FindPartOnRayWithIgnoreList and find the position of where its being hit:

local hit, position = workspace:FindPartOnRayWithIgnoreList (Ray, IgnoreList)

You can use the variable position to get the 3D position of the gui.

If you want the object , make use of the variable hit and just check that its the object you’re looking for.

It’s a bit hard to tell if you want the CFrame or not from your original thread.

Also take into consideration, when the user moves their camera you’ll get different results.

If you want to get the CFrame

Step 6: Make use of CFrame.new() this takes in two parameters in this case. CFrame.new(Position, LookAt):

local CFrame = CFrame.new(CurrentCamera.CFrame.lookVector, Position)

Position represents what has been returned from FindPartOnRayWithIgnoreList.

Please do mention any issues with this reply too!

8 Likes

Thank you very much :slight_smile: !

1 Like