Can't figure out how to rotate object to point at another

I have a compass tool that when equipped Instances a glowing arrow on the player. I want this arrow to point to a set position in the game where there is a hidden treasure chest, and rotate around the player as they move to hint at where that treasure is.

The issue I’m having is that I can’t figure out a way to smoothly rotate the arrow to the correct direction without it bugging out the player, like in these videos. I want it to just smoothly spin to the correct position and then wait there without moving or rotating the actual player. The setup for the arrow is the arrow piece is hinged to an anchor part which is welded to the HRP of the player. This setup lets the arrow spin freely around the y-axis, which is what I want, but when I try to change the rotation in code it’s weird.

Here is the code I’m using, it’s on a localscript in the tool:

-- Services
local RS = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

-- References
local tool = script.Parent
local player = Players.LocalPlayer
local skullChest = workspace.SkullChest
local CompassArrow = RS.Objects.CompassArrow
local arrowClone

-- Treasure found flip
local foundTreasure = false
local equipped = false

-- Create glowing arrow
tool.Equipped:Connect(function()
	if foundTreasure == false then
		
		equipped = true
		
		arrowClone = CompassArrow:Clone()
		arrowClone.Parent = player.Character
		arrowClone.Anchor.Position = player.Character.HumanoidRootPart.Position
		arrowClone.GlowingArrow.Position = arrowClone.Anchor.Position
		local weld = Instance.new("WeldConstraint", arrowClone)
		weld.Part0 = player.Character.HumanoidRootPart
		weld.Part1 = arrowClone.Anchor
		print("created arrow")
		
	end
end)
-- Remove glowing arrow
tool.Unequipped:Connect(function()
	if foundTreasure == false then
		
		equipped = false
		
		arrowClone:Destroy()
		arrowClone = nil
	end
end)


RunService.RenderStepped:Connect(function()
	if equipped then
		local newAngle = Vector3.new(0, math.deg(math.atan((skullChest.Wood.Position.Z - arrowClone.GlowingArrow.Position.Z) / (skullChest.Wood.Position.X - arrowClone.GlowingArrow.Position.X))), 0)
		print(newAngle)
		arrowClone.GlowingArrow.Rotation = newAngle
	end
end)


Any help would be very appreciated, I’m pretty new to roblox scripting!

3 Likes

Change arrowClone.CanCollide to false

ArrowClone already has CanCollide set to false, sorry I should have specified that. I just turned it on in one video to show how it rotated around the hinge.

A pure mathematical approach could be

local Direction = (arrowClone.Position - skullChest.Wood.Position).Unit
arrowClone.CFrame = CFrame.lookAt(arrowClone.Anchor.Position, arrowClone.Anchor.Position + Direction)
—if this points the weong way, switch CFrame.lookAt to CFrame.lookAt(arrowClone.Anchor.Position + Vector3.new(Direction.X,0,Direction.Y), arrowClone.Anchor.Position)
1 Like

Not sure if something like this is what you’re looking for but this should work well and give a smooth arrow that points towards the skullChest when equipping the Compass, just edit the code to your liking.

local skullChest = game.Workspace.SkullChest
local player = game:GetService("Players").LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local tool = script.Parent
local mainPart = CompassArrow.PrimaryPart

local renderConnection

local foundTreasure = false
local equipped = false

CompassArrow.Parent = game.Workspace

-- Create glowing arrow
tool.Equipped:Connect(function()
	if foundTreasure == false then
		
		
		equipped = true
		
		renderConnection = game:GetService("RunService").RenderStepped:Connect(function()
				mainPart.CFrame = CFrame.lookAt(char.HumanoidRootPart.Position, game.Workspace.SkullChest.PrimaryPart.Position)
		end)
	end
end)

-- Remove glowing arrow
tool.Unequipped:Connect(function()
	if foundTreasure == false then
		
		
		equipped = false
		
		renderConnection:Disconnect()
		CompassArrow:Destroy()
	end
end)
2 Likes

That helped thanks! This is the final code I got, I ended up using a BallSocketConstraint on the CompassArrow model, this let it rotate freely and orient towards the chest without trying to drag or rotate the player. Much better than using a HingeConstraint:

-- Services
local RS = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

-- References
local tool = script.Parent
local player = Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local skullChest = workspace.SkullChest
local CompassArrow = RS.Objects.CompassArrow


local arrowClone
local mainPart
local renderConnection

-- Treasure found flip
local foundTreasure = false
local equipped = false

-- Create glowing arrow
tool.Equipped:Connect(function()
	if foundTreasure == false then
		
		equipped = true
		
		arrowClone = CompassArrow:Clone()
		arrowClone.Parent = char
		arrowClone.Anchor.Position = char.HumanoidRootPart.Position
		arrowClone.GlowingArrow.Position = arrowClone.Anchor.Position
		local constraint = Instance.new("BallSocketConstraint", arrowClone)
		constraint.Attachment0 = char.HumanoidRootPart.RootAttachment
		constraint.Attachment1 = arrowClone.Anchor.Attachment
		
		mainPart = arrowClone.Anchor
		
		renderConnection = RunService.RenderStepped:Connect(function()
			mainPart.CFrame = CFrame.lookAt(mainPart.Position, skullChest.PrimaryPart.Position)
		end)
		
		print("created arrow")
		
	end
end)
-- Remove glowing arrow
tool.Unequipped:Connect(function()
	if foundTreasure == false then
		
		equipped = false
		
		arrowClone:Destroy()
		arrowClone = nil
	end
end)

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