Roblox Studio Compass Quest

Alright so, as the title implies I’m trying to create a compass system which has a quest track on top of it and it shows where the quest location is. As the example shows:
image_2023-01-22_085735365

I searched through every place/forum and platform in order to find some type of approach or open sourced material but wasn’t able to find anything connected to LUA/Roblox.

Much appreaciated!

2 Likes

What do you have so far? Do you have the GUI set up and/or some attempts at scripting it?

I do have a simple compass script which moves to whichever way the player looks but thats all there is. I haven’t tried any further scripting about the quest mark since I don’t even understand the approach of it.

1 Like

Well, the details depend on how exactly you want it to work. Do you want the compass to stay fixed or turn with the camera?

Alright my fault for not giving any specific details since I doubted somebody will actually answer, so here are more details.
I’m sure you most certainly played games such as “The Elder Scrolls” and “Elden Ring”. The compass
If not here is an example of what I meant it to look like:
p29W1c4
But the only difference is that I would want it to be for the only active quest for the player.

1 Like

Okay, so here’s an illustration of situation from a top-down perspective:

You can imagine the black bold arc segment is like the compass bar in the GUI. The black dots along the circle show how the marker’s position along the compass bar depends on the angle between the camera’s look direction (the black arrow) and the vector from the players position (blue circle in the center) to the marker point (ends of the blue arrows).

At the same time you might want to display cardinal directions (N, S, W, E). For those you don’t need to calculate the angle based on the position, they just have a fixed angle.

We’ll need to calculate the angle of a vector2 in 2d. For that we have atan2. One thing to know is that atan2 takes a y value first and then an x value. This shows atan2 in a Cartesian coordinate system:

image

As you can see it’s the angle between the x axis and the point. That’s fine, except we kind of expect positive angles to be a turn to the right (in the GUI compass bar), because positive X is to the right in GUI space. No problem, just negate the output of atan2 to get the desired results.

It’s convenient to work with the markers’ world points relative to the camera, so first we convert any given point to the cameras object space. Then get the angle the camera would have to turn to face the point:

function rotationToFaceTowardsPoint(camera: Camera, point: Vector3): number
     local relativePoint = camera.CFrame:PointToObjectSpacePoint)
     local angle = -math.atan2(relativePoint.X, -relativePoint.Z)
     return angle
end

The NSWE direction stuff works like this:

local NORTH = Vector3.xAxis
local SOUTH = -NORTH
local EAST = Vector3.zAxis
local WEST = -EAST

function rotationToFaceInDirection(camera: Camera, direction: Vector3): number
    local relativeDirection = camera:VectorToObjectSpace(direction)
    local angle = -math.atan(relativeDirection.X, -relativeDirection.Z)
end

Great, we can compute the angle the camera would need to turn to face any point or direction. Now to place the markers on the GUI compass bar. Like in the first figure, you’ll need to choose some “field of view” for the compass bar. I chose 90, but it could be any angle really and you should play around with it to see what feels nice.

Say the center of the bar is 0 degrees, the left edge is -fovAngle/2 and the right edge is +fovAngle/2. Since GUI positions work from 0 = left edge to 1 = right edge, we need to convert:

function rotationToGuiPosition(rotation, fovAngle)
    return rotation / fovAngle + 0.5
end

You can check that it works like this:

for a = -45, 45, 15 do
    print(a, math.floor(rotationToGuiPosition(a, 90)*100)/100)
end

yep, the left of the field of view (-45) is the left of the GUI element (0), and same for the right (+45, 1).

Then you just have to create GUI elements inside the compass bar that somehow know what point or direction to track, and update them every frame by setting their position accordingly. You can set ClipsDescendants to true on the compass bar to have markers disappear from view, or clamp the position in the range [0, 1] to have them stay at the edge of the bar. Or even get fancy and calculate some appropriate transparency for each compass marker.

4 Likes

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