Hello! I’m working on something for a group and the idea is this: A static image (A top down view of the map via an image not a camera.) with player positions being represented by triangles. I don’t want the map to follow the player.
Something like this:
However I don’t know how I would take player positions in the 3D space and project them onto the 2D GUI accurately, any help?
So the GUI is 2d meaning you only need 2 coordinates, that being X and Z
Now, how to convert the position of the world into the GUI? First figure out the size of the GUI, im just gonna say (200, 50) for this explanation. Then figure out the size of the area your minimap is supposed to cover, ill give a random number like (1200, 600)
GUI Size: (200, 50)
Map Size: (1200, 600)
Now divide the Map Size by the GUI Size
1200 / 200 = 6
600 / 50 = 12
To get an accurate projection of the player positions in the 3d space on to the 2d space, you must divide the 3d X by 6 and the 3d Y by 12.
If I was at Map Position (500, 200), I would be at the middle left of the minimap.
I’m not too sure this is the correct explanation but you can go and test this out, this was from the top of my head, ask questions
the guisize is the size of the imagelabel, the minimap is the imagelabel and the map size is the size of the map being represented by the minimap, for your first question you probably have to do more math to convert it
Helo Shiver, This is a mini-map I recently made. It follows the player around the map with an arrow showing which direction they are pointing. The map has 3 modes: hidden, small, and large that the player cycles through by clicking the M-key. A screenshot and the map structure are shown below. The script RunContext is Client. I try to size and position everything with Scale (not Offset) so it is easy to resize and position things.
local UserInputService = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local guiMap = player.PlayerGui:WaitForChild("ScreenGuiMap")
local guiMapFrame = guiMap:WaitForChild("Frame")
local guiMapMap = guiMapFrame:WaitForChild("ImageLabelMap")
local guiMapCursor = guiMapFrame:WaitForChild("ImageLabelCursor")
local positionX
local positionZ
local terrainSizeX = 8192 -- uploaded terrain size
local terrainSizeZ = 8192
local mapState = "small" -- off, small, large in that order
local function updateMap()
if UserInputService:IsKeyDown(Enum.KeyCode.M) then
if mapState == "small" then
guiMap.Enabled = true
mapState = "large"
guiMapFrame.Size = UDim2.new(0.3, 0, 0.45, 0)
elseif mapState == "large" then
mapState = "off"
guiMap.Enabled = false
else
guiMap.Enabled = true
mapState = "small"
guiMapFrame.Size = UDim2.new(0.1, 0, 0.15, 0)
end
end
end
UserInputService.InputBegan:Connect(updateMap)
-- the following logic is to prevent the loop from running both in StarterGui and Players/player/PlayerGui
local loop = false
if script:FindFirstAncestorOfClass("PlayerGui") then loop = true end
while loop do
positionX = character.HumanoidRootPart.Position.X
positionZ = character.HumanoidRootPart.Position.Z
positionX = 0.5 + positionX/terrainSizeX -- convert this to a position scale on gui map
positionZ = 0.5 + positionZ/terrainSizeZ
positionX = math.clamp(positionX,0,1)
positionZ = math.clamp(positionZ,0,1)
guiMapCursor.Position = UDim2.new(positionX, 0, positionZ, 0)
local Y = rootPart.Orientation.Y
guiMapCursor.Rotation = -Y
task.wait(0.5)
end