Hello everyone, i tried to create a cool effect when the character moves so that it tilts in every direction but i couldn’t do it and then i searched and found this code right here it works just fine but i don’t understand the math behind it

local 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)
end)

I know that the dot product of two normalized vectors give the cosine of the angle between the two vectors but it seems like it just gives the right angle right away

First gets the velocity of the root part and cancels the y axis input

It then gets the unit of the velocity (direction with magnitude of 1) and gets the dot product between the camera’s right vector and the velocity which defines the relationship between the direction of two vectors. 1 if they are in same direction, 0 if they are perpendicular and -1 if they are opposite. So for example if the character is moving right this would return ~1 as the vectors point to the same direction. Where as if he were to move left, it would return ~-1 as the vectors are opposite. The value is then divided by a number to lower the value so it can be used as radian (low radians are equivalent to a high degree).

The same is done for between the camera’s look vector and the velocity. So if the character were to move straight, it would return ~1 or if it were to move backwards, the result would be ~-1.

In all other cases, for eg when character is moving diagonally, produces a value between -1 and 1. So essentially the tilt is reduced.

The dot products are then used as angles (in radians) and applied to the weld of the HRP by multiplying the C0 (which is weld stuff; will require an entire article to explain that. for now just remember that modifying the rotation of C0 will apply the rotation to character’s torso). The dot product obtained in the first case is used to rotate the character along the Y axis (not right and left but the motion which happens when you turn back in real life) and that obtained in the second case is used to rotate character along the x-axis (up and down).

For more understanding here’s a table which shows value of dot product in degrees.

Dot product

Angles

1

57.3

0.5

28.6

0

0

-0.5

-28.6

-1

-57.3

Notice how the angle decreases as we move to 0 (opposite vectors). So the angle of tilt is dependent upon the relationship of vectors I mentioned above. If you are moving right, the angles will be at its maximum (57.3 so high tilt). If you are moving diagonally the angles will be half of the max angle (28.6 so slight tilt) and if you are completely still, the angle will be 0 (no tilt)