How to rotate weld's C1 value to make part face a position?

There are MANY posts with issues similar to mine. However, after searching extensively, I could not find a post that gives a straight forward answer to solve this issue. Here is my situation:

local character = workspace.Rig
local targetPos = Vector3.new()

local rightShoulder = character.Torso['Right Shoulder']
local leftShoulder = character.Torso['Left Shoulder']

rightShoulder.Enabled = false
leftShoulder.Enabled = false

local rightWeld = Instance.new('Weld')
rightWeld.Part0 = character.Torso
rightWeld.Part1 = character['Right Arm']
rightWeld.C0 = CFrame.new(1, 0.5, 0)
rightWeld.C0 *= CFrame.Angles(0, math.pi / 2, 0)
rightWeld.C1 = CFrame.new(-0.5, 1, 0)
rightWeld.C1 *= CFrame.Angles(0, math.pi / 2, 0)
rightWeld.Name = 'RightShoulder'
rightWeld.Parent = character.Torso

local leftWeld = Instance.new('Weld')
leftWeld.Part0 = character.Torso
leftWeld.Part1 = character['Left Arm']
leftWeld.C0 = CFrame.new(-1, 0.5, 0)
leftWeld.C0 *= CFrame.Angles(0, -math.pi / 2, 0)
leftWeld.C1 = CFrame.new(0.5, 1, 0)
leftWeld.C1 *= CFrame.Angles(0, -math.pi / 2, 0)
leftWeld.Name = 'LeftShoulder'
leftWeld.Parent = character.Torso

To explain what I have so far, I have begun by referencing and disabling the motor6d’s that connect the character’s arms. Secondly, I created welds to take the place of the motor6d’s which also prevents arms from being animated. Afterwards, I set the C0 and C1 of each weld to whatever values they were on their respective motor6d (Note: It appears that for the C1 and C0 values of each motor6d, there is a 90 degree rotation on the y-axis. For the left side its a -90 degree rotation on the y-axis.). Lastly, I set the name and parent the welds to the torso of the character.

The issue I am faced with is that, even after extensively looking on the Devforum, I could not figure out a way to rotate the C1 value to make the arm face towards a position. I thought about using trigonometry but those trig functions are very expensive (for what I have heard). I need a solution that is the most straight-forward approach with the least code possible and IDEALLY USES NO TRIG FUNCTIONS (if that is possible). Please don’t suggest CFrame.lookAt() if you think this post is about making a part face a position.

Also, because there are many scripters with this similar issue, I have worded the title of the post such so that it most likely is to pop up when someone researches their similar issue. Being so, please explain your solution because it is very appreciated!

Thanks for the help!

1 Like

Don’t know if this works but you can give a try

local cf = lookAtCFrame:Inverse() * arm.CFrame
weld.C1 *= -cf.Rotation
1 Like

Your code does not work and it errors. I don’t know If I implemented your logic correctly but here is a screenshot that shows my code.

Note that the arm’s CFrame is not the same as the base C0 of the weld. Being so, there is no real reason to include the arm’s CFrame when trying to solve this issue.

2 Likes

(Bump)

This issue further persists. I have found somewhat of a solution though.

The code in the posts works and has the correct behavior of making the arms of the character face a target position by changing the weld’s c1 offset (see below).

while true do 
	if tick() - start >= 2 then break end
	game.ReplicatedStorage.ClickAnimating:Fire()
	wait()
	local offset = CFrame.new(0,0,-0.5)*CFrame.Angles(math.pi/2,0,0)
	local p0c0 = torso.CFrame*weld1.C0

	weld1.C1 = (CFrame.new(p0c0.p, FB.Position)*offset):inverse()*p0c0
	local p0c0 = torso.CFrame*weld2.C0
	weld2.C1 = (CFrame.new(p0c0.p, FB.Position)*offset):inverse()*p0c0 
end

Editing the code provides the intended behavior I am looking for. Although this is a solution, I will not mark it as such. Although the code does edit the C1 value, it requires an offset variable. Here is a piece of code I found that does not require such offset variable.

This piece of code does not require a offset variable but the issue is that it manipulates the C0 offset instead of the C1 offset. The goal is to do what this piece of code does but to make it so it changes the C1 offset rather than the C0 offset.

Edit: If you found the solution then please do remember to explain the logic of the code in depth! Thanks!

2 Likes

(Bump)

Has anybody yet found a solution to this issue?

2 Likes

The code wasn’t tested and I thought Roblox had a way to reverse the rotation matrix of the cframe. Turns out im wrong lol. Anyways I’ll test later in studio and lyk if anything works out.

So idk how accurate my method was, but this was my thought process. Since both C0 and C1 are offsets, I thought I could just get the difference in rotation between the two parts (arm and lookout part) and add it onto the offset. I used arm.CFrame cuz afaik it is the final result after applying C0 and C1 (atleast rotation wise)

2 Likes

Do you need to use normal welds? I originally used them to animate a tank, however I too ran into this problem. I could not find a way to make the turret face a target while the hull was moving arbitrarily.

I ended up using weld constraints to connect parts. Very simple, and all you need to do to make sure any CFrame manipulations don’t propagate to any unwanted parts is to simply disable the weld constraint connecting them.

For instance…

local weldCon = character.Torso["Right Arm"]

weldCon.Enabled = false
-- Do stuff
weldCon.Enabled = true

Now, you could do something like creating a part that acts as the socket for the arm, weld constraint the two together (and the socket to the torso), and just manipulate the socket with CFrame.lookAt(). This will allow the arm to stay in the socket while pointing at the target part.

1 Like

The title is very specific for a reason. I need to understand how to manipulate a weld’s, not a weld constraint, C1 value in order to make the Part1 face an object. So far I figured out how to accomplish this by manipulating the C0 but I need to be able to do so by manipulating the C1.

1 Like

Care to elaborate why you need a weld specifically? Weld constraints are easier to use and have the same functionality.

1 Like

Weld constraints do not have a C0 value and a C1 value. What is C1 and C0? In a weld we have the Part0, this is the part that Part1 is WELDED TO. If we did not have the C0 and C1 values, Part1 will be welded to Part0 by its origin. But, if we have a C0 value of CFrame.new(0, -1, 0) Part1 will be welded to Part0’s origin with the offset of -1 on the y-axis. C1 is the exact same thing but handles the offset for Part1. This allows more control on how a part is welded to another part. As to why I want to use a weld, I don’t want to change too much about the character’s model by adding weld constraints and extra parts that act as a way for me to pivot the arms. Instead I have just created 2 welds that essentially replace the arm motor6d’s.

That’s fair. Just know that if it doesn’t work out, you do have another solution.

1 Like

(Bump)

I found out that the X component of the vector3 in the welds acts as the yaw and the Z component acts as the pitch. If this helps with finding a solution.

1 Like

(Bump)

Still no solution. (30 letter limit)

Hey you said my post is kinda a solution. You can always just remove the offset or set it to 0,0,0. the offset just makes it so the arms don’t look wonky!!!

Here’s the working and updated version of my code!!!
I say mine only cuz the post its mostly my friend’s who helped me with the math lol.

repeat task.wait() until torso:FindFirstChild("Left Shoulder")
local lShoulder=torso:WaitForChild("Left Shoulder");--the left shoulder weld
local rShoulder=torso:WaitForChild("Right Shoulder");--the Right shoulder weld

local la0,la1=lShoulder.C0,lShoulder.C1;
local ra0,ra1=rShoulder.C0,rShoulder.C1;

local LBW=Instance.new("Weld",torso);--backup left shoulder weld
local RBW=Instance.new("Weld",torso);--backup right shoulder weld

local PlayerPosition = plr.Character.PrimaryPart.Position
RBW.Part0,RBW.Part1=rShoulder.Part0,rShoulder.Part1;
LBW.Part0,LBW.Part1=lShoulder.Part0,lShoulder.Part1;
rShoulder.Part0,rShoulder.Part1=nil,nil;
lShoulder.Part0,lShoulder.Part1=nil,nil;
		

function ChangeWeld(weld,pos)
	if not weld.Part0 then return; end
	local desired_p1=CFrame.new(--the CFrame that we want the arm to be at
		(weld.Part0.CFrame).p+(pos-(weld.Part0.CFrame).p).unit,--the position we want
		pos--look at the part
	)*
		CFrame.Angles(math.pi/2,0,0);--rotate it so that the hand points that way
	weld.C0=CFrame.new();--set C0 to identity matrix so it is out of the equation
	weld.C1=desired_p1:inverse()*weld.Part0.CFrame;--same equation as shown above
end

for i=0,100 do
	local Part = nil; --Put here
	ChangeWeld(RBW,Part.Position);
	ChangeWeld(LBW,Part.Position);
	task.wait();
end