I noticed that when using the scale tool on the right arm in studio, it adjusts the joint connected to it to remain in the intended alignment.
For example in the first and second picture you can see how the arm aligns with the torso normally, and in the third and fourth picture I use the scale to adjust the size of the arm, it still aligns perfectly.
It seems like studio adjusts the c1 property of the Right Shoulder motor allowing the joint to keep its intended alignment. In the examples I use the c1 property of the Right Shoulder joint as the right arms pivot offset to rotate about the point.
How would I accomplish this in a script so the joints keep intended alignment regardless of size changes of the joint’s part0 or part1 properties?
Never had to do this, but it stands to reason that since c0 and c1 are relative to the origin of part0 and part1 respectively you’d just rescale c0 / c1 proportional to the limb whose size is being changed. Edit: I haven’t tested but sticking this in any rig should do the job. Edit: Had some issues but now working.
Still has problems, give me a bit. Or feel free to fix up the code underneath if I take too long.
local function MakeConnection(motor6d, part, cType)
local baseSize = part.Size
local baseCFrame = motor6d[cType]
part:GetPropertyChangedSignal("Size"):Connect(function()
local difference = part.Size - baseSize
motor6d[cType] = CFrame.new(difference / 2) * baseCFrame
end)
end
for _, motor6d in ipairs(script.Parent:GetDescendants()) do
if motor6d.ClassName ~= "Motor6D" then
continue
end
MakeConnection(motor6d, motor6d.Part0, "C0")
MakeConnection(motor6d, motor6d.Part1, "C1")
end
This revised version works for the limbs. It technically also works for the torso but the c1 for the other limbs joined to the torso don’t change. The head also doesn’t change or is positioned awkwardly but it seems like you are on the right track.
Alright, here you are. No idea why the first approach didn’t work.
local function MakeConnection(motor6d, part, cType)
local baseSize = part.Size
local baseCFrame = motor6d[cType]
local baseAngle = CFrame.Angles(baseCFrame:ToEulerAnglesXYZ())
local basePosition = baseCFrame.Position
part:GetPropertyChangedSignal("Size"):Connect(function()
local scale = part.Size / baseSize
motor6d[cType] = CFrame.new(basePosition * scale) * baseAngle--baseCFrame --* CFrame.new(difference / 2)
end)
end
for _, motor6d in ipairs(script.Parent:GetDescendants()) do
if motor6d.ClassName ~= "Motor6D" then
continue
end
MakeConnection(motor6d, motor6d.Part0, "C0")
MakeConnection(motor6d, motor6d.Part1, "C1")
end
Edit: Didn’t realize how funny that background music would be to a video of a robloxian getting eviscerated
Will require custom animations to not look odd, though.
Otherwise you’re gonna have to take care of those quirks on a case by case basis. Since motor6ds are offset from the origin of the part, the shoulder motor6ds aren’t biased towards staying a set distance from the top face to make the arms connect like that.
Roblox is able to cheat this a bit because the resize tool allows you to indicate a direction you want to extrude the limb in. That information is lost when simply making the limb larger. A direct function would be preferable.
The goal was to give players different r6 sizes similar to how r15 rig scales itself with player preferences., so not sure if manually rescaling would work.
So far I noticed at least for arms, the y component of the c1 on the right shoulder joint is 25% of the right arms size, but there is some offset of the size differs from the torso’s y size and/or if the arm doesnt have the same size ratio as the normal arm’s proportion (arms/legs size usually = limbX, limbX*2, limbX)
I will post if I end up finding something that works, if not I will just change joints as suggested.
This is how it would look like if we were to emulate how roblox does it. Again, it’d be on a case-by-case basis; this is just in one axis.
local function ExtrudeLimbY(limb, motor6d, studs)
limb.Size += Vector3.new(0, studs, 0)
motor6d.C1 *= CFrame.new(0, studs / 2, 0)
end
local arm = script.Parent["Right Arm"]
local motor = script.Parent.Torso["Right Shoulder"]
ExtrudeLimbY(arm, motor, 1)
Im now using your original method of adjusting the motor properties with the size change.
To tell the direction I have a another function tell me whether or not to invert each pivot component based on if the original motor property is above the center or below the center.
This seems to work so far with the original alignment of the r6 rig motors. Will do a few more tests.
local function getDelta(originalSize, newSize)
local offset = Vector3.new(
newSize.X/2 - originalSize.X/2,
newSize.Y/2 - originalSize.Y/2,
newSize.Z/2 - originalSize.Z/2
)
return offset
end
local function getDirection (originalMotorCF)
return Vector3.new(
(originalMotorCF.Position.X == 0 and 0) or (originalMotorCF.Position.X > 0 and 1) or -1,
(originalMotorCF.Position.Y == 0 and 0) or (originalMotorCF.Position.Y > 0 and 1) or -1,
(originalMotorCF.Position.Z == 0 and 0) or (originalMotorCF.Position.Z > 0 and 1) or -1
)
end
local function adjustMotor (motor, part, cType)
local originalSize = part.Size
local orignalCFrame = motor[cType]
local dir = getDirection(orignalCFrame)
part:GetPropertyChangedSignal("Size"):Connect(function ()
local dummyCF = CFrame.new(orignalCFrame.Position) * CFrame.new(getDelta(originalSize, part.Size) * dir)
motor[cType] = dummyCF * orignalCFrame.Rotation
end)
end
for _, xMotor in pairs (script.Parent:GetDescendants()) do
if not (xMotor:IsA("Motor6D")) then continue end
adjustMotor(xMotor, xMotor.Part1, "C1")
adjustMotor(xMotor, xMotor.Part0, "C0")
end
It might already be accounted for, but I would just make sure this method works with a rig at various different orientations and with rescaling a limb on more than one axis as a time.
If you manage to get it to be completely reliable you could probably post this in community resources. I’d check to make sure it works with r15 too, though.
After testing I still noticed that for some scales though the limbs align, rotating the limbs don’t align with how the original r6 rigs rotates. I will keep looking at this to see if I can find a solution.