Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Trying to make a part point to another object while in the Player's Character?

Asked by 6 years ago
Edited 6 years ago

So I've got the part (which is an arrow) in the player's character, I'm just having trouble with making it point at the object in the workspace, Below I have attached the code I'm using, I figured the last piece of code would make the arrow point at a part called QUESTOBJECTIVEPOS but it just makes the arrow go really far away from the character.

wait(0.1)

Player = game.Players.LocalPlayer
character = Player.Character
arrow = game.ReplicatedStorage.Arrow:Clone()

arrow.CFrame = character.HumanoidRootPart.CFrame * CFrame.new(0, 0, -5) * CFrame.Angles(math.rad(0), math.rad(0), math.rad(90))

local Joint = Instance.new("Weld")
Joint.Part0 = arrow     
Joint.C0 = arrow.CFrame:inverse()       
Joint.Part1 = character.HumanoidRootPart    
Joint.C1 = character.HumanoidRootPart.CFrame:inverse()

Joint.Parent = character.HumanoidRootPart
arrow.Parent = character

game:GetService("RunService").RenderStepped:connect(function()
    arrow.LocalTransparencyModifier = 0
end)

i = 1, math.huge
while wait() do
    i = i + 1
    Joint.C0 = CFrame.Angles(0, 0, math.rad(i)) * Joint.C1 * CFrame.new(game.Workspace.QUESTOBJECTIVEPOS.Position)
end


1 answer

Log in to vote
0
Answered by
XAXA 1569 Moderation Voter
6 years ago
Edited 6 years ago

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.C1 = ??? -- We'll adjust this in the loop.
Joint.Parent = HumanoidRootPart

Arrow.Parent = Character

game:GetService("RunService").RenderStepped:Connect(function()
    --Joint.C1 = ??? -- Adjust Weld.C1 here.
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.)

0
Thank you this helped me so much I <3 you!!! greybird700 63 — 6y
Ad

Answer this question