Custom body tilting when moving character

Hey y’all,
I was trying to make a custom movement system and wanted to make the player character tilt towards the direction they’re moving, like this:

I’ve tried messing with the RootWeld’s C0 and C1 but I couldn’t get anything to work… Any ideas on how I could achieve this?
I’m fine with just a concept, I don’t necessarily need a whole script.

!! I don’t know if this can help, but the character can only be R6.

Thank you in advance!

EDIT: This has been solved, but for anyone who eventually finds this post in the future, this is the code:

local Angle = 15 -- Change this value however you want

local Plr = game:GetService("Players").LocalPlayer
local HRootPart = Plr.Character.PrimaryPart
local Humanoid = Plr.Character.Humanoid

local OriginalC0 = HRootPart.RootJoint.C0

RBXCs.BodyTilt = game:GetService("RunService").RenderStepped:Connect(function()
	
	local XDirection = Humanoid.MoveDirection:Dot(HRootPart.CFrame.LookVector)
	local ZDirection = -Humanoid.MoveDirection:Dot(HRootPart.CFrame.RightVector)
	
	HRootPart.RootJoint.C0 = HRootPart.RootJoint.C0:Lerp(originalC0 * CFrame.Angles(math.rad(Angle*XDirection),math.rad(Angle*ZDirection),0), .2)
	
end)

Personally, I put this script inside the character so instead of getting the player I can simply type local Character = script.Parent and not have to deal with resetting, dying, etc.
If you want to make the tilting faster / more responsive, tweak with the final Lerp value a bit (higher = faster tilting)

1 Like

Essentially in a localscript, you can compare RootPart.CFrame.LookVector with Humanoid.MoveDirection (Dot product) to see if you are moving sideways. Then use that to change Root joint’s C0 (or C1) like this:

-- Define angle by how steeply are you going left or right
Root.C0 = OriginalC0 * CFrame.Angles(ANGLE,0,0)

Hope this helps you get started! :smiley:

1 Like

Thank you so much, this works perfectly.
I didn’t know about dot and cross product before now, so this opened up a whole world for me.
Thank you again!

No problem! Glad I was able to help :smiley: Good luck on your project!

1 Like

For anyone who eventually finds this post in the future, this is the code:

local Angle = 15 -- Change this value however you want

local Plr = game:GetService("Players").LocalPlayer
local HRootPart = Plr.Character.PrimaryPart
local Humanoid = Plr.Character.Humanoid

local OriginalC0 = HRootPart.RootJoint.C0

RBXCs.BodyTilt = game:GetService("RunService").RenderStepped:Connect(function()
	
	local XDirection = Humanoid.MoveDirection:Dot(HRootPart.CFrame.LookVector)
	local ZDirection = -Humanoid.MoveDirection:Dot(HRootPart.CFrame.RightVector)
	
	HRootPart.RootJoint.C0 = HRootPart.RootJoint.C0:Lerp(originalC0 * CFrame.Angles(math.rad(Angle*XDirection),math.rad(Angle*ZDirection),0), .2)
	
end)

Personally, I put this script inside the character so instead of getting the player I can simply type local Character = script.Parent and not have to deal with resetting, dying, etc.
If you want to make the tilting faster / more responsive, tweak with the final Lerp value a bit (higher = faster tilting)

I do recommend not using RenderStepped for this since it runs way more often then you need. Simple Stepped or Heartbeat should be plenty for your need :smiley:

1 Like