How to convert a CFrame to an Udim2?

Im currently trying to make a map, but i need a way to convert the players postion to a point on a Map gui, how would i do that.
Ive already look around and tried Camera:WorldToScreenPoint(PlayerPos) but it returns some really wierd values so idk.

1 Like

You’ll have to find the minimum and maximum values in the world you want to translate to the map. To find this value easily I would recommend putting an invisible brick in the top-left corner (minBrick) and another in the bottom-right corner (maxBrick), then use an inverse lerp function like so

local minBrick: Part
local maxBrick: Part

local function player_to_map(playerWorld: CFrame)
	local x = (playerWorld.Position.X - minBrick.Position.X) / (maxBrick.Position.X - minBrick.Position.X)
	local y = (playerWorld.Position.Z - minBrick.Position.Z) / (maxBrick.Position.Z - minBrick.Position.Z)

	return UDim2.new(x, 0, y, 0)
end

ok, ill try that and ill let you know if it worked or not

well i have a diffrent problem blocking me from testing, the parts are just deleting themselfs, they are anchored

Can you show your script and explorer?

grafik
the red parts are deleting them selfes

To convert a player’s position (CFrame) to a point on a GUI map (UDim2), you need to scale and translate the player’s position in the game world to fit within the boundaries of the map. Here’s a function to do that:

-- Function to convert CFrame to UDim2 for a map GUI
-- playerPosition: The player's CFrame position
-- mapSize: The size of the map GUI in pixels (Vector2)
-- worldSize: The size of the world in studs (Vector2)
-- worldCenter: The center of the world in studs (Vector2)
function cframeToUdim2(playerPosition, mapSize, worldSize, worldCenter)
    local scaledX = (playerPosition.X - worldCenter.X) / worldSize.X
    local scaledZ = (playerPosition.Z - worldCenter.Y) / worldSize.Y
    
    local mapX = 0.5 + scaledX / 2
    local mapY = 0.5 - scaledZ / 2
    
    return UDim2.new(mapX, 0, mapY, 0)
end

Here’s an example of how to use the function with a player’s position and a map GUI:

local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

local mapSize = Vector2.new(400, 400) -- Set this to the size of your map GUI in pixels
local worldSize = Vector2.new(1000, 1000) -- Set this to the size of your world in studs
local worldCenter = Vector2.new(0, 0) -- Set this to the center of your world in studs

local playerPosition = character.HumanoidRootPart.Position
local mapPosition = cframeToUdim2(playerPosition, mapSize, worldSize, worldCenter)

print("Player's map position: ", mapPosition)

This will convert the player’s position in the game world to a point on a map GUI. You can use mapPosition to position a GUI element, such as an ImageLabel, to represent the player’s location on the map.

Please note that this example assumes a flat, 2D world, with only the X and Z coordinates being considered for the conversion. You may need to adjust the function depending on the specifics of your game world.

1 Like

this seems to be kinda working, altho the position of the dot is incorrect the dot should be somewhere in the red area
grafik
the code:

There might be some issues with the scaling and translation of the player’s position in the function. Let’s try adjusting the function with different scaling and translation factors.

Try the following updated function:

-- Function to convert CFrame to UDim2 for a map GUI
-- playerPosition: The player's CFrame position
-- mapSize: The size of the map GUI in pixels (Vector2)
-- worldSize: The size of the world in studs (Vector2)
-- worldCenter: The center of the world in studs (Vector2)
function cframeToUdim2(playerPosition, mapSize, worldSize, worldCenter)
    local scaledX = (playerPosition.X - worldCenter.X) / worldSize.X
    local scaledZ = (playerPosition.Z - worldCenter.Y) / worldSize.Y
    
    local mapX = (0.5 * scaledX + 0.5) * mapSize.X
    local mapY = (0.5 * -scaledZ + 0.5) * mapSize.Y
    
    return UDim2.new(0, mapX, 0, mapY)
end

This function scales the player’s position by the mapSize to get the exact pixel coordinates on the map GUI. Please test the function with your map GUI and see if the dot’s position is more accurate. If it still doesn’t work as expected, you may need to adjust the scaling and translation factors based on your game world and map GUI.

the plr is even more off, what scaling and translation factors do i need to edit?
grafik

Let’s try another approach to calculate the map position using a different scaling and translation method.

-- Function to convert CFrame to UDim2 for a map GUI
-- playerPosition: The player's CFrame position
-- mapSize: The size of the map GUI in pixels (Vector2)
-- worldSize: The size of the world in studs (Vector2)
-- worldCenter: The center of the world in studs (Vector2)
function cframeToUdim2(playerPosition, mapSize, worldSize, worldCenter)
    local scaleX = mapSize.X / worldSize.X
    local scaleZ = mapSize.Y / worldSize.Y
    
    local offsetX = (playerPosition.X - worldCenter.X) * scaleX
    local offsetY = (playerPosition.Z - worldCenter.Y) * scaleZ
    
    local mapX = offsetX + mapSize.X * 0.5
    local mapY = -offsetY + mapSize.Y * 0.5
    
    return UDim2.new(0, mapX, 0, mapY)
end

This function calculates the scaling factors by dividing the map size by the world size. Then, it calculates the offset by multiplying the player’s position (relative to the world center) with the scaling factors. Finally, it adds half of the map size to the offsets to get the final map position.

Please test this function with your map GUI and see if the dot’s position is more accurate. If it still doesn’t work as expected, you may need to adjust the scaling and translation factors further based on your game world and map GUI.

nothing has changed, and i dont want to be rude but your replies sound like they came from an AI

2 Likes

Indeed, they sound like AI because I use them to fix sentences or errors to understand and add extra details.

1 Like

Are they placed below 500Y? I don’t know why they would delete if they are anchored and above the kill-floor. Your script certainly doesn’t do that.

Also you do not need to wrap the heartbeat connection in a coroutine.

i realized that StreamingEnabled is “despawing” them is there another way without the parts?

1 Like

if you know where the parts reside you can copy their positions directly into the script instead.

local minPosition: Vector3
local maxPosition: Vector3

local function player_to_map(playerWorld: CFrame)
	local x = (playerWorld.Position.X - minPosition.X) / (maxPosition.X - minPosition.X)
	local y = (playerWorld.Position.Z - minPosition.Z) / (maxPosition.Z - minPosition.Z)

	return UDim2.new(x, 0, y, 0)
end
2 Likes

this gets the right X Position but the wrong Y Position
grafik

Interesting, I noticed the last time you posted the script you were subtracting the wrong minimum position. make sure it’s max.Z - min.Z not max.Z - min.X. if that still doesn’t work try flipping the Z to Ys, maybe I am getting the coordinate system wrong.

i used the script you provided, and i changed the Z’s to Y’s but noting changed
versions i tried:
grafik
grafik

Maybe the position’s Z/Y are wrong, you could print the y value and multiply your minimum and maximum position.Z by what ever it shows (since it will probably be negative switch the printed value to positive)