The RootJoint
is a Motor6D used for animation and moving around the character. It’s commonly used for animations, but in the odd case can be used for CFrame Manipulation
, which sounds really cool but in reality it’s just glorified animating. It’s basically animating things by modifying their Motor6D C0 and C1 properties instead of just… animating. People usually do this for games which don’t allow you to import your animations (e.g Lua Sandbox, a Roblox game where you can create your own scripts and execute them inside of it with other people). In your case though, this makes sense. You don’t want to create an animation for that.
I can’t really provide much code, since I don’t usually do stuff like this, but I can tell you how it works.
-- Properly indent your code please!
local Tilt = CFrame.new()
runService.RenderStepped:Connect(function(Delta)
local MoveDirection = rootPart.CFrame:VectorToObjectSpace(humanoid.MoveDirection) -- This returns the "direction" of your movement. When testing, I found that walking straight forward without any rotation returns around Vector3.new(0, 0, -1) or similar.
Tilt = Tilt:Lerp(CFrame.Angles(math.rad(-MoveDirection.Z) * MaxTiltAngle, math.rad(-MoveDirection.X) * MaxTiltAngle, 0), 0.2 ^ (1 / (Delta * 60)))
-- This converts your "move direction" into a CFrame by converting your move direction into an angle.
-- math.rad(-MoveDirection.Z) is saying "convert this vector into a rotation value readable by the machine, and then amplify the effect of the movement by the specified angle the player provides"
-- :Lerp() is commonly used for CFrame Manipulation. It provides a smooth movement, as that second argument tells the game how much percentage you want to move the tilt to their destination. I explain it after this code block.
RootJoint.C0 = RootC0 * Tilt
end)
Lerping is a function that can be executed on CFrames by calling the method, and then providing two arguments. The first argument is the CFrame you want the final destination to be, and the second argument is the percentage of how much you want to move it. It’s a bit odd, though, since 100% in the second argument of Lerp
is just 1
. So you need to divide the percent you want by 100. So if you wanted the CFrame to move to 10% of the way to the CFrame destination specified, you would say 0.1
. Odd, I know.
“Wouldn’t lerping just provide a linear movement?”
Yep! In this case, though, the developer changes the Tilt
value every frame and then lerps it again! This means that every time you’re basically making it smooth. Let me try and explain in simple terms:
Imagine you’re cutting a pie in half every swing of your knife. Swing it once, it’s in half. Swing it again, now it’s in quarters. Eights, so on, and so on. That’s basically what’s happening. It continuously halves itself (or atleast, I think it is in the code. I am NOT figuring out that math even if it’s actually probably really simple lol) until it inevitably reaches the destination. An issue with this method of smooth lerping: it never truly reaches its destination. Lets go back to that pie analogy: you continuously cut the pie in half and half and half and half, eights, sixteenths, thirty-twos, and so on. But you never truly finish cutting the pie. You just keep going and going and going. It might look like you’re there, but you really not. So if you’re relying on checking if a :Lerp()
method has reached its destination, don’t.
Not a very good explanation, but it was the best I could do. Hope I helped even a tiny bit!