Getting surface gui position from world position?

Currently, I’m trying to find a way to get the position on a surface gui based on a WorldPosition

Example of what I need:

How would I achieve this?

1 Like

Raycast down via the part’s negative upvector.

I already have the world position, but thats not what I’m asking. I’m wondering how id turn the world position into a position on a surface gui

I believe the following works.

local guiPart = workspace:WaitForChild("GuiPart")
local part = workspace:WaitForChild("Part")
local surfaceGui = script.Parent

local guiPartStartX = guiPart.Position.X - guiPart.Size.X/2
local partPositionFromStartX = part.Position.X - guiPartStartX
local ratioX = partPositionFromStartX / guiPart.Size.X
print(ratioX)

local guiPartStartZ = guiPart.Position.Z - guiPart.Size.Z/2
local partPositionFromStartZ = part.Position.Z - guiPartStartZ
local ratioZ = partPositionFromStartZ / guiPart.Size.Z
print(ratioZ)
	
local partPositionOnGuiX = surfaceGui.AbsoluteSize.X * ratioX
local partPositionOnGuiZ = surfaceGui.AbsoluteSize.Y * ratioZ
print(partPositionOnGuiX, partPositionOnGuiZ)

Here’s the reproduction file:
repro.rbxm (5.3 KB)

1 Like

I can’t seem to get this to work. Could you provide this working for you?

What I’m using:

local guiPart = workspace:WaitForChild("GuiPart")
local part = workspace:WaitForChild("Part")
local surfaceGui = script.Parent

while task.wait(.03) do
	
	local guiPartStartX = guiPart.Position.X - guiPart.Size.X/2
	local partPositionFromStartX = part.Position.X - guiPartStartX
	local ratioX = partPositionFromStartX / guiPart.Size.X

	local guiPartStartZ = guiPart.Position.Z - guiPart.Size.Z/2
	local partPositionFromStartZ = part.Position.Z - guiPartStartX
	local ratioZ = partPositionFromStartX / guiPart.Size.Z

	local partPositionOnGuiX = surfaceGui.AbsoluteSize.X * ratioX
	local partPositionOnGuiZ = surfaceGui.AbsoluteSize.Y * ratioZ
	print(partPositionOnGuiX, partPositionOnGuiZ)
	
	
	surfaceGui.ImageLabel.Position = UDim2.fromOffset(partPositionOnGuiX, partPositionOnGuiZ)


end


1 Like

https://gyazo.com/9793315664407abb9a051be54db5dbcf

In case you’re wondering, the ImageLabel is in the center of the part, depth is what makes it look like it isn’t.

local guiPart = workspace:WaitForChild("GuiPart")
local part = workspace:WaitForChild("Part")
local surfaceGui = script.Parent
local frame = surfaceGui:WaitForChild("Frame")
local image = frame:WaitForChild("ImageLabel")

task.spawn(function()
	while task.wait(0.1) do
		local guiPartStartX = guiPart.Position.X - guiPart.Size.X/2
		local partPositionFromStartX = part.Position.X - guiPartStartX
		local ratioX = partPositionFromStartX / guiPart.Size.X
		print(ratioX)

		local guiPartStartZ = guiPart.Position.Z - guiPart.Size.Z/2
		local partPositionFromStartZ = part.Position.Z - guiPartStartZ
		local ratioZ = partPositionFromStartZ / guiPart.Size.Z
		print(ratioZ)
			
		local partPositionOnGuiX = surfaceGui.AbsoluteSize.X - surfaceGui.AbsoluteSize.X * ratioX
		local partPositionOnGuiZ = surfaceGui.AbsoluteSize.Y * ratioZ
		print(partPositionOnGuiX, partPositionOnGuiZ)
		image.Position = UDim2.new(0, partPositionOnGuiX, 0, partPositionOnGuiZ)
	end
end)

while task.wait(1) do
	local random = math.random(1, 2)
	if random == 1 then
		part.Position += Vector3.new(math.random(), 0, math.random())
	elseif random == 2 then
		part.Position -= Vector3.new(math.random(), 0, math.random())
	end
end
1 Like

This still doesn’t work, it only works diagonally

1 Like

Did you check the gif above? It’s working for me along both axis.

1 Like

Yes, inside of your gif it’s only going diagonally, try dragging the part around. It needs to work anywhere

1 Like

You’re right, thanks for sharing, I noticed some minor typos which I’ve fixed, here’s the script I have now.

local guiPart = workspace:WaitForChild("GuiPart")
local part = workspace:WaitForChild("Part")
local surfaceGui = script.Parent
local frame = surfaceGui:WaitForChild("Frame")
local image = frame:WaitForChild("ImageLabel")

task.spawn(function()
	while task.wait(0.1) do
		local guiPartStartX = guiPart.Position.X - guiPart.Size.X/2
		local partPositionFromStartX = part.Position.X - guiPartStartX
		local ratioX = partPositionFromStartX / guiPart.Size.X
		local guiPartStartZ = guiPart.Position.Z - guiPart.Size.Z/2
		local partPositionFromStartZ = part.Position.Z - guiPartStartZ
		local ratioZ = partPositionFromStartZ / guiPart.Size.Z
		local partPositionOnGuiX = surfaceGui.AbsoluteSize.X * ratioX
		local partPositionOnGuiZ = surfaceGui.AbsoluteSize.Y - surfaceGui.AbsoluteSize.Y * ratioZ
		image.Position = UDim2.new(0, partPositionOnGuiZ, 0, partPositionOnGuiX)
	end
end)

while task.wait(1) do
	local random = math.random(1, 2)
	if random == 1 then
		part.Position += Vector3.new(math.random(), 0, math.random())
	elseif random == 2 then
		part.Position -= Vector3.new(math.random(), 0, math.random())
	end
end

repro.rbxm (7.3 KB)

Here’s proof it works now:
https://gyazo.com/c5c0404854c91d4ea681d028b07deced

6 Likes

It’s working, thank you!

(3 0 cha r)

1 Like