Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Creator @DutchDeveloper has made a really useful video explaining how [Mad City](https://www.roblox.com/games/1224212277/Mad-City) created their point markers and as he isn't able to post in here yet I'm doing it on his behalf.
- Video:
- https://www.youtube.com/watch?v=JYkiPs6wk4k
- # Tutorial:
- ----
- **How the markers work:**
- In ReplicatedStorage there's a folder called 'Markers' and in the folder theirs a part, this part is the position of the marker. In each location there's a folder called Config, this holds the information about each marker such as if it's enabled, the icon and the icon colour.
- ![image|197x183](upload://tv5R7eXlfK8bZgOt9IbnOrFMUZr.png)
- In the ScreenGui there is one local script and a frame called 'Holder', the 'Holder' is placed in the centre of the screen and has it provides the distance from each of the sides of the screen (screen size).
- ![image|273x205](upload://pNocSgUQ9pFilAUiK8Y0COEqBJb.png)
- The sample is a 0.05 sized circle with a UIAspectRatioConstraint to keep it square. Then, we've got a frame called 'RotateLabel'. This contains the image with the arrow pointing toward the location. As well, it contains the icon of the location that you've set in the 'Config' folder.
- ![image|226x201](upload://kAIEITR7uP3Q8ELiss1rltQFuPt.png)
- This goes through the folder 'Markers' and makes a label in the 'Holder' frame and stores the location and label inside a table called 'Markers'.
- ```LUA
- local Markers = {}
- local Screen = script.Parent.Holder.AbsoluteSize
- local T = game:GetService("TweenService")
- for i,v in pairs(game.ReplicatedStorage.Markers:GetChildren()) do
- local Sample = script.Sample:Clone()
- Sample.Parent = script.Parent.Holder
- Sample.ImageColor3 = v.Config.IconCollor.Value
- Sample.RotateLabel.Arrow.ImageColor3 = v.Config.IconCollor.Value
- Sample.Icon.Image = v.Config.Icon.Value
- table.insert(Markers,{Sample,v})
- end
- ```
- We're using a RenderStepped loop and go through the list of markers. First, we're checking if the marker is enabled, if it isn't it will not render. Then we're calculating where the position is into 2D space. If you look away normally it would still show the marker as it was there. That's why we're checking the Z value of the Vector3 we're receiving. Then we're putting the X, Y and absolute size into the function 'findClosestBorderPoint'. This will clamp the value to the left, right, top or bottom sides so it will not show inside the middle of your screen. If we're facing the marker then we're preventing it from going away from the edge of the screen. As well, we're using the value called 'InViewport' to show the arrow when you're not facing the location.
- ```LUA
- function findClosestBorderPoint(x,y,Absolute)
- x = Screen.X - x
- y = Screen.Y - y
- local distanceToYBorder = math.min(y,Screen.Y-y)
- local distanceToXBorder = math.min(x,Screen.X-x)
- if distanceToYBorder < distanceToXBorder then
- if y < (Screen.Y - y) then
- return math.clamp(x,0,Screen.X-Absolute.X),0
- else
- return math.clamp(x,0,Screen.X-Absolute.X),Screen.Y - Absolute.Y
- end
- else
- if x < (Screen.X - x) then
- return 0,math.clamp(y,0,Screen.Y-Absolute.Y)
- else
- return Screen.X - Absolute.X,math.clamp(y,0,Screen.Y-Absolute.Y)
- end
- end
- end
- game:GetService("RunService").RenderStepped:Connect(function()
- for i,v in pairs(Markers) do
- local Marker = v[1]
- local Location = v[2]
- if not Marker == nil or Location == nil then
- table.remove(Markers,i)
- end
- Marker.Visible = Location.Config.Enabled.Value
- if Location.Config.Enabled.Value then
- local MarkerPosition, inViewport = workspace.CurrentCamera:WorldToScreenPoint(Location.Position)
- local MarkerRotation = workspace.CurrentCamera.CFrame:inverse()*Location.CFrame
- local MarkerAbsolute = Marker.AbsoluteSize
- local MarkerPositionX = MarkerPosition.X - MarkerAbsolute.X/2
- local MarkerPositionY = MarkerPosition.Y - MarkerAbsolute.Y/2
- if MarkerPosition.Z < 0 then
- MarkerPositionX,MarkerPositionY = findClosestBorderPoint(MarkerPositionX,MarkerPositionY,MarkerAbsolute)
- else
- if MarkerPositionX < 0 then
- MarkerPositionX = 0
- elseif MarkerPositionX > (Screen.X -MarkerAbsolute.X) then
- MarkerPositionX = Screen.X - MarkerAbsolute.X
- end
- if MarkerPositionY < 0 then
- MarkerPositionY = 0
- elseif MarkerPositionY > (Screen.Y -MarkerAbsolute.Y) then
- MarkerPositionY = Screen.Y - MarkerAbsolute.Y
- end
- end
- Marker.Position = UDim2.new(0,MarkerPositionX,0,MarkerPositionY)
- Marker.RotateLabel.Visible = not inViewport
- Marker.RotateLabel.Rotation = 90+math.deg(math.atan2(MarkerRotation.Z, MarkerRotation.X))
- end
- end
- end)
- ```
- That's a basic understanding of how this script works, if you'd like to see anymore please check out the video above.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement