How do i make my compass point at a part?

Currently, i have this compass that points north. But I wan’t to make it point to a part instead.

How would i achieve this?


current code:

HumanoidRootPart = script.Parent.Parent.Parent:FindFirstChild("HumanoidRootPart")


while true do
	wait(0)
	if HumanoidRootPart then
		script.Parent.Parent.ArrowPart.SurfaceGui.Needle.Rotation = -HumanoidRootPart.Orientation.Y
	end
end
1 Like

I spent quite a while getting this to work, so hopefully it works in your case.

local HumanoidRootPart = script.Parent.Parent.Parent:FindFirstChild("HumanoidRootPart")
-- ^ this is the part that it will point to ^
local ArrowPart = script.Parent.Parent

while wait() do
	if HumanoidRootPart then
		local pos = ArrowPart.Position - HumanoidRootPart.Position
		ArrowPart.SurfaceGui.Needle.Rotation = 90 - math.deg(math.atan(pos.X / pos.Z))
	end
end

Edit: made some optimisations.

1 Like

What does math.atan do?

(30 chars)

That returns the arc tangent of x.

1 Like

Gradient is the speed at which a slope rises per increment of the x axis.
Gradient is calculated as (y2 - y1) / (x2 - x1)
Arctan gets the angle from a gradient.
Arctan is calculated as x / math.sqrt(1 + x ^ 2) (x being the gradient)

Roblox implementation here: Atan roblox
Wiki page on it here: Inverse trigonometric functions

1 Like

Thanks, but it doesn’t seem to work that well.

Turning your character doesn’t affect the compass, and sometimes the arrow will randomly flip

And if you wan't to see the edited code
RS.RenderStepped:Connect(function()
	if Equipped and CompassGoal.Value and HumanoidRootPart then
		local pos = HumanoidRootPart.Position - CompassGoal.Value.Position
		ArrowPart.SurfaceGui.Needle.Rotation = 180 - math.deg(math.atan(pos.X / pos.Z))
	elseif CompassGoal.Value == nil then
		warn("CompassGoal is nil or missing")
	end
end)

should be

CompassGoal.Value.Position - HRP.Position

The reason it doesn’t turn when your player turns is because your using the HumanoidRootPart and the main part of the compass.
It also appears to be switching around the 90/270 deg mark, try removing the 180 - .

None of that has seemed to have change much.

Also doing that doesn’t fix the issue.

My goal is to try and get the compass arrow tip to always face at the part.

First off, the compass needle is relative to your HumanoidRootPart, you would want to switch that to the main part of the compass (so that the needles rotation is relative to the compass and not the player).

Try the following to fix the weird north/south glitch

RS.RenderStepped:Connect(function()
	if Equipped and CompassGoal.Value and HumanoidRootPart then
		local pos = HumanoidRootPart.Position - CompassGoal.Value.Position
		local rot = -math.deg(math.atan2(pos.X, pos.Z)) + 90
		if rot < 0 then
			rot = rot + 360
		end
		ArrowPart.SurfaceGui.Needle.Rotation = rot
	elseif CompassGoal.Value == nil then
		warn("CompassGoal is nil or missing")
	end
end)
2 Likes

That fixes that issue, but still doesn’t always point to the part unless the compass is in a certain orientation.

BUT that is an easy fix

all i had to do was change that to

local rot = -math.deg(math.atan2(pos.X, pos.Z)) + HRP.Orientation.Y

Thanks for your help Jayz

You could try a CFrame constructor aswell

local RunService = game:GetService("RunService")
local PointPart = workspace:WaitForChild("PointPart") --the part where you want it to point
local Needle = Compass.Needle --The needle

RunService.Heartbeat:Connect(function()
    if PointPart then
        Needle.CFrame = CFrame.new(Needle.CFrame.p, PointPart.CFrame.p * Vector3.new(1, 0, 1))
    end
end)

``` I tested it and it was quite smooth

Yeah, that’s easy to do with a part. But the compass is using a SurfaceGui.

But thanks anyway!

1 Like