Removing torso rotation

game.StarterPack.LocalScript:

local char=game:GetService'Players'.LocalPlayer
char=char.Character or char.CharacterAdded:Wait()
game:GetService'RunService'.Stepped:Connect(function(dt)
	local upper=char.UpperTorso
	local waist=upper.Waist
	local lower=char.LowerTorso
	local hrp=char.HumanoidRootPart
	local lowerloc=hrp.CFrame:inverse()*lower.CFrame
	waist.Transform=(waist.C0-waist.C0.p):inverse()*(lowerloc-lowerloc.p):inverse()*(waist.C1-waist.C1.p)
	print((hrp.CFrame:inverse()*upper.CFrame):ToEulerAnglesXYZ())
end)

https://developer.roblox.com/api-reference/property/Motor6D/Transform
How can I make the torso 0 rotation relative to the humanoid root part?

or is this just calculation errors?

Thanks

R15: create 2 welds:

Weld 1) Part0 = HumanoidRootPart; Part1 = UpperTorso

Weld 2) Part0 = HumanoidRootPart; Part1 = LowerTorso

*Edit the weld C0 for Weld 1 and 2

R6
Weld) Part0 = HumanoidRootPart; Part1 = Torso
*Edit the weld C0 for Weld

This is probably the most reliable method that I can think of.

1 Like

I would like it to use the existing motor6ds because I am overlaying extra (a second and sometimes a third) Roblox animations on top, I am just using this to remove the first animation’s UpperTorso transformation caused by animating the LowerTorso

also, even though it looks like its just calculation errors, I’m experiencing jittering :confused:
here is video if it helps

or am i blind lol

i dont, i have use my own ots camera, i just didnt disable shift lock
and anyways that is irrelevant

Well you shouldn’t be updating the rotation like that if you want to keep it smooth…

Weld it once to the humanoid, and then it will be 0 rotation (Frame-Of-Reference: HumanoidRootPart)

I think the best way to solve this would be implementing your own animations for your character, since the real reason there would be any offset between the torso and the HumanoidRootPart would be from the (first) animation rotating the torso the tiniest bit.
The built-in Animate script that comes with the character contains StringValues as children which let you easily change AnimationId’s on the fly, and you can simply copy and paste this script into StarterCharacterScripts in StarterPlayer, with the new AnimationId’s applied.

image

Hopefully, that helps.

1 Like

We are using custom movement animations, but the problem is that when you shift the lowertorso, the uppertorso shifts too (its an intrinsic property of roblox animations)

So just updating the movement animations will not work for me (movement animations without the lowertorso moving look a little strange), that is why I am trying to negate the transformations applied

Thanks for posting though :man_shrugging:

1 Like

Is there a notable difference between using RunService.Stepped, RunService.RenderStepped, and RunService:BindToRenderStep?

it’s probably a bad idea to ask here, but it might be something you didn’t think about?

1 Like

Here is a chart that shows the rendering order: (it was taken from an RDC 2019 keynote)

So Stepped is right before physics while renderstepped (and bindtorenderstep) is right before rendering

New property: Motor6D.Transform says to only use Stepped when dealing with the Transform property, so I do not believe you can use something else here (I initially was doing BindToRenderStep but it was not working)

As for the difference between BindToRenderStep and RenderStepped:
Testing with this code:

game:GetService'RunService':BindToRenderStep('test',Enum.RenderPriority.First.Value,function()
	print'first'
end)

game:GetService'RunService':BindToRenderStep('test2',Enum.RenderPriority.Last.Value,function()
	print'last'
end)
game:GetService'RunService':BindToRenderStep('test3',Enum.RenderPriority.First.Value+1,function()
	print'first+'
end)

game:GetService'RunService':BindToRenderStep('test4',Enum.RenderPriority.Last.Value+1,function()
	print'last+'
end)
game:GetService'RunService':BindToRenderStep('test5',Enum.RenderPriority.First.Value-1,function()
	print'first-'
end)

game:GetService'RunService':BindToRenderStep('test6',Enum.RenderPriority.Last.Value-1,function()
	print'last-'
end)

game:GetService'RunService'.RenderStepped:Connect(function()
	print'deprecated;P'
end)

game:GetService'RunService'.Heartbeat:Connect(function()
	warn'new frame'
end)
game:GetService'RunService':BindToRenderStep('test6',2^30,function()
	print'last+++++++++++++++++'
end)

Yields:

so RenderStepped fires immediately after all of BindToRenderStep priorities-interestingly, priorities a little more than 2^30 go before the lowest priorities

My guess is that RenderStepped was introduced before BindToRenderStep, and should be deprecated since you have more control with BindToRenderStep (you can set the priorities-which is quite necessary to avoid hacky code[although I would argue this in it of itself is hacky])

1 Like