Positioning the outline
To position the white outline, you’ll need to convert the player’s position in the game world to a different coordinate space, corresponding to the player’s position on the minimap. You’ll need to know:
- The player’s position in the game world
- The size of the level (the side length, in studs)
This assumes that the level is square, centered on (0, 0, 0)
(although the Y coordinate doesn’t matter), and that the level and minimap are rotated the same. The camera should also point in a direction such that pressing W
(or whatever corresponds to moving “into” the screen in your game) makes the character move in the -Z direction, and pressing D
should make the player’s X coordinate increase.
Converting between world- space and minimap- space coordinates is as simple as
local levelScale = 100 --however many studs long the side of your level is
function toMinimapSpace(worldPoint)
--Convert from a world- space Vector3 point to a minimap- space UDim2 Position
local minimapV3 = worldPoint / levelScale
return UDim2.new(
0.5 + minimapV3.X, 0, --minimap X scale coordinate
0.5 + minimapV3.Z, 0 --minimap Y scale coordinate
)
end
function toWorldSpace(minimapPoint)
--Convert from a minimap- space UDim2 Position to a world- space Vector3 point
return Vector3.new(
minimapPoint.X.Scale * (levelScale - 0.5), --world X coordinate
0,
minimapPoint.Y.Scale * (levelScale - 0.5) --world Z coordinate
)
end
You'll probably want to update the white outline every frame, which you can do like so:
local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()
local cameraOutline = script.Parent.Frame
game:GetService("RunService").RenderStepped:Connect(function( dt )
local playerPosition = character.HumanoidRootPart.Position --or some other way of getting the player's position
cameraOutline.Position = toMinimapSpace(playerPosition)
end)
This also assumes that CameraOutline is a GuiElement whose center corresponds to the point on the minimap where the outline should be centered. That means its’ AnchorPoint
should be 0.5, 0.5
. You can make the edges of the outline with 1-pixel wide frames. It also assumes that the position (0, 0, 0, 0)
corresponds exactly to the upper-left corner of the image of the map, and that (1, 0, 1, 0)
is exactly the lower right corner.
The size of the outline
If you think about it, the area of the ground (a horizontal plane) that is visible to the camera (assuming there is line of sight) the shape of the intersection of the camera’s view frustum and that plane. If the camera is pointed straight down, that shape is a rectangle. Otherwise, it’s some weird wonky shape. That means we can’t make the outline correspond exactly to what’s visible from the camera. That’s probably fine though, or at least it looks like that’s what LoL does too.
Basically, we’ll have to find some decent approximation of the size of the area. Here’s an illustration of the camera from a side view. If you plan on only ever allowing one camera field of view, and never move the camera up or down, then you can just set the height manually to something that’s close enough.
You can’t rely on the width though, because as player’s screen aspect ratios increase, so will their horizontal field of view.
We can get away with just multiplying the height of the outline by the screen aspect ratio, like so:
local outlineHeight = 0.12 --the Scale Y part of the Size of the outline, adjust to fit your needs
function aspectRatio( camera )
return camera.ViewportSize.X / camera.ViewportSize.Y
end
game:GetService("RunService").RenderSteped:Connect(function( dt )
local playerPosition = character.HumanoidRootPart.Position --or some other way of getting the player's position
cameraOutline.Position = toMinimapSpace(playerPosition)
cameraOutline.Size = UDim2.new(outlineHeight * aspectRatio(), 0, outlineHeight, 0)
end)
If you need to do more accurate calculations, or if anything is unclear, then let me know.