How do I tilt the character's torso without tilting legs?

Currently this tilting script tilts the entirety of the character like this:


But I wish for it to only rotate the upper body and leave the feet untilted (stays perpendiculaire to the ground), this is the current script I have:

--< Services >--
local RunService = game:GetService("RunService")

--< Player >--
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart")
local RootJoint = hrp:WaitForChild("RootJoint")
local torso = char:WaitForChild("Torso")

local Direction, Force
local Value1 = 0
local Value2 = 5

local RootJointC0 = RootJoint.C0

RunService.RenderStepped:Connect(function()
	Force = hrp.AssemblyLinearVelocity * Vector3.new(1, 0, 1)
	if Force.Magnitude > 0.001 then
		Direction = Force.Unit
		Value1 = hrp.CFrame.RightVector:Dot(Direction)
	else
		Value1 = 0
	end

	RootJoint.C0 = RootJoint.C0:Lerp(RootJointC0 * CFrame.Angles(0, math.rad(-Value1 * Value2), 0), 0.2)
2 Likes

That would be a lot of math to get it right but here is what I’ve done

llocal dir, vel
local angle = 0
local angle2 = 0

local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()

local root = char:WaitForChild("HumanoidRootPart")
local Joint = root:WaitForChild("RootJoint")
local LeftLegJoint = Joint.Part1:WaitForChild("Left Hip")
local RightLegJoint = Joint.Part1:WaitForChild("Right Hip")
local OriginalPos = Joint.C0
local OriginalLeftlLegPos = LeftLegJoint.C0
local OriginalRightLegPos = RightLegJoint.C0

local DevideAngle = 2.5
local DevideAngle2 = 2.5
local TiltSpeed = .3

game:GetService("RunService").Heartbeat:Connect(function()
	vel = root.Velocity * Vector3.new(1,0,1)
	if vel.Magnitude > 2 and vel.Magnitude < 20 then
		dir = vel.Unit
		angle = root.CFrame.RightVector:Dot(dir) / DevideAngle
		angle2 = root.CFrame.LookVector:Dot(dir) / DevideAngle2
	else
		angle = 0
		angle2 = 0
	end
	
	Joint.C0 = Joint.C0:Lerp(OriginalPos * CFrame.Angles(angle2, -angle, 0),TiltSpeed)   
	LeftLegJoint.C0 = LeftLegJoint.C0:Lerp(OriginalLeftlLegPos * CFrame.Angles(angle,0,-angle2),TiltSpeed)
	RightLegJoint.C0 = RightLegJoint.C0:Lerp(OriginalRightLegPos * CFrame.Angles(-angle,0,angle2),TiltSpeed)
end)

https://gyazo.com/46b46847473b23b0f3dc27ee29dc387c.mp4

6 Likes

This is very fabulous work! Thank you very much for sharing this!

1 Like

Hey by the way, you don’t need the and vel.Magnitude < 20, that messes with the tilting if the humanoid speed changes, so instead it should be like this:

local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()

local root = char:WaitForChild("HumanoidRootPart")
local Joint = root:WaitForChild("RootJoint")
local LeftLegJoint = Joint.Part1:WaitForChild("Left Hip")
local RightLegJoint = Joint.Part1:WaitForChild("Right Hip")
local OriginalPos = Joint.C0
local OriginalLeftlLegPos = LeftLegJoint.C0
local OriginalRightLegPos = RightLegJoint.C0

local DevideAngle = 2.5
local DevideAngle2 = 2.5
local TiltSpeed = .3

local dir, vel
local angle = 0
local angle2 = 0

game:GetService("RunService").Heartbeat:Connect(function()
	vel = root.AssemblyLinearVelocity * Vector3.new(1,0,1)
	if vel.Magnitude > 1 then
		dir = vel.Unit
		angle = root.CFrame.RightVector:Dot(dir) / DevideAngle
		angle2 = root.CFrame.LookVector:Dot(dir) / DevideAngle2
	else
		angle = 0
		angle2 = 0
	end
	
	Joint.C0 = Joint.C0:Lerp(OriginalPos * CFrame.Angles(angle2, -angle, 0),TiltSpeed)   
	LeftLegJoint.C0 = LeftLegJoint.C0:Lerp(OriginalLeftlLegPos * CFrame.Angles(angle,0,-angle2),TiltSpeed)
	RightLegJoint.C0 = RightLegJoint.C0:Lerp(OriginalRightLegPos * CFrame.Angles(-angle,0,angle2),TiltSpeed)
end)

Thanks again for sharing this!

5 Likes