Here's your script. I rewrote it a bit to make it easier to read:
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Arrow = game.ReplicatedStorage.Arrow:Clone()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Objective = workspace:WaitForChild("QUESTOBJECTIVEPOS")
local Joint = Instance.new("Weld")
Joint.Part0 = HumanoidRootPart
Joint.Part1 = Arrow
Joint.C0 = CFrame.new()
Joint.Parent = HumanoidRootPart
Arrow.Parent = Character
game:GetService("RunService").RenderStepped:Connect(function()
end)
We're looking to adjust Joint.C1 such that it would make Arrow point to Objective. To do that, we need to look at how welds work at a lower level:
Part1.CFrame * C1 == Part0.CFrame * C0
Substitution Part1 for Arrow, Part0 for HumanoidRootPart, and C1 and C0 we get:
Arrow.CFrame * Joint.C1 == HumanoidRootPart.CFrame * Joint.C0
We know what Arrow.CFrame should be (five studs above HumanoidRootPart, looking at Objective), and we know what HumanoidRootPart.CFrame is at any given time. Furthermore, since we set Joint.C0 to CFrame.new(), anything we multiply to it will remain the same (CFrame.new() is the identity matrix. Just like 1 in algebra, anything multiplied to it will remain the same), so we can just choose to omit it.
CFrame.new(HumanoidRootPart.Position + Vector3.new(0, 5, 0), Objective.Position) * Joint.C1 = HumanoidRootPart.CFrame
(From here on out, let's call CFrame.new(HumanoidRootPart.Position + Vector3.new(0, 5, 0) "offset" to save space)
local offset = CFrame.new(HumanoidRootPart.Position + Vector3.new(0, 5, 0), Objective.Position)
offset * Joint.C1 = HumanoidRootPart.CFrame
We want to isolate Joint.C1 such that it is alone on its side of the equation. To do that, we can multiply the left side of each side by offset:inverse() (note the :inverse() part. A matrix (CFrame) multiplied by its inverse will result in an identity matrix (CFrame.new()), which we could then cancel out.
This equation:
local offset = CFrame.new(HumanoidRootPart.Position + Vector3.new(0, 5, 0), Objective.Position)
offset:inverse() * offset * Joint.C1 = offset:inverse() * HumanoidRootPart.CFrame
simplifies to
local offset = CFrame.new(HumanoidRootPart.Position + Vector3.new(0, 5, 0), Objective.Position)
Joint.C1 = offset:inverse() * HumanoidRootPart.CFrame
Viola, we've solved for Joint.C1.
Here's the final script:
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Arrow = game.ReplicatedStorage.Arrow:Clone()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Objective = workspace:WaitForChild("QUESTOBJECTIVEPOS")
local Joint = Instance.new("Weld")
Joint.Part0 = HumanoidRootPart
Joint.Part1 = Arrow
Joint.C0 = CFrame.new()
Joint.Parent = HumanoidRootPart
Arrow.Parent = Character
game:GetService("RunService").RenderStepped:Connect(function()
local offset = CFrame.new(HumanoidRootPart.Position + Vector3.new(0, 5, 0), Objective.Position)
Joint.C1 = offset:inverse() * HumanoidRootPart.CFrame
end)
(I'm going to be very honest, since you're changing the CFrame of the arrow every frame anyway, you're better of just not using welds at all and setting the CFrame of the arrow directly.)
1 comment
Thank you this helped me so much I <3 you!!!