Help With Distance Math

So my game is setup where there’s a lobby and then changing maps that wrap around the lobby like this:
image

Now I want to create a square minimap that looks like this:
image

The minimap would display everyone’s position on the in game map. Although, it’s complicated since it’s hard to figure out where to position each player on the minimap.

My idea on how to tackle this is to have 4 parts that represent each section, and then I would SpatialQuery each part to figure out which characters are in what region. Then have attachments on each end of each part and triangulate the HumanoidRootPart position along with the 2 points to figure out where each character was located in each part.

image

So for example if a player was on the left region of the map, the script would get the two points in that region (the blue dots) and triangulate with the character’s root part (the green dot) and somehow figure out where the player is and spit out a decimal from 0-1 which I can then use to set the position of that player’s icon on the minimap.

Although, the problem is I’m only a freshman and I don’t know where to even begin with the math and coding for this :skull:

Feel free to ask questions if I explained this badly :‎P

2 Likes

bump…

thirty-character limitt

1 Like

What you are attempting to do, if I understand correctly, is take the position of a character relative to the world map, and position a dot representing them in a mini-map.

To do this, instead of creating regions and “triangulate” the position relative to the frame using attachments, I would just take the position of the character’s HumaniodRootPart (which can be accessed by the client through the workspace) and then divide it by the world map’s total size. This would get the position of the character relative to the map (using scale).

I am working on an example right now and will post it once it is complete. Let me know if you have any other questions or concerns.

1 Like

So basically forget triangulation and just make it work like a normal minimap, and since there is barriers to the map, the players will still align with the square? I don’t know why I didn’t think of that lmao

1 Like

Correct. Sorry for the delay. The script would just use the world map model, getting the overall size of it, and convert that relative to the player position, giving you the scale position of the player relative to the mini-map frame.

Here is an image that might help with what I have explained thus far:

The problem with doing this is that the frame starts in the top-left (0, 0), however, the world map starts in the middle (0, 0). To get around this, we can just take the frame and make (0, 0) the middle of the frame, using math.

When converting the world position relative to the frame, we just have to subtract the relative position (player.Position/map.Size) from half of the size of the map ((map.Size/2)/map.Size).

Here is a script that should do everything that I have explained (Local Script, placed under the frame that represents the mini-map):

-- Mini Map Script

-- Constants
local PLAYER_COLOR = Color3.new(1,0,0)

local DOT_SIZE = UDim2.new(.05,0,.05,0)
local DOT_CORNER = UDim.new(1,0)

-- Variables
local run_service = game:GetService("RunService")

local players = game:GetService("Players")
local player = players.LocalPlayer

local map: Frame = script.Parent
local world_map: Model = workspace.WholeMap

-- Functions
function Convert_Pos_To_Scale(position: Vector3): UDim2	
	return UDim2.fromScale(
		(world_map:GetExtentsSize().X/2)/(world_map:GetExtentsSize().X) - position.X/world_map:GetExtentsSize().X,
		(world_map:GetExtentsSize().Z/2)/(world_map:GetExtentsSize().Z) - position.Z/world_map:GetExtentsSize().Z
	)
end

function Get_Player_Pos(selected_player: Player): Vector3
	local character = selected_player.Character or selected_player.CharacterAdded:Wait()
	return character.HumanoidRootPart.Position
end

function Create_Dot(position: UDim2, selected_player: Player)
	local new_dot = map:FindFirstChild(selected_player.Name) or Instance.new("Frame", map)
	local corner = Instance.new("UICorner", new_dot)
	local aspect_ratio = Instance.new("UIAspectRatioConstraint", new_dot)
	
	new_dot.Name = selected_player.Name
	new_dot.BackgroundColor3 = PLAYER_COLOR
	new_dot.Size = DOT_SIZE
	new_dot.Position = position
	
	corner.CornerRadius = DOT_CORNER
	aspect_ratio.AspectRatio = 1
end

function Create_Map()
	for _, selected_player in pairs(players:GetPlayers()) do
		local selected_player_pos = Get_Player_Pos(selected_player)
		local converted_pos = Convert_Pos_To_Scale(selected_player_pos)
				
		Create_Dot(converted_pos, selected_player)
	end
end

-- Initialize
run_service.RenderStepped:Connect(function(dt)
	Create_Map()
end)

Let me know if you have any further questions or need help figuring out how to get this to work for you!

EDIT: Here are the results when I test it


3 Likes

Thank you :goat:

I appreciate how much extra effort you put into this :slight_smile:
This means a lot and will accelerate my workflow

1 Like

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