How would I make a character turn effect?

I want to make it so that when your character turns, it’s torso/rootpart rotates, I have seen this beautiful effect somewhere in 2018 and I have wanted to make one since. Never got it to work.

No matter how hard I tried I couldn’t get it right, no matter what I did! I have tried using BodyGyros, set different CFrames for the BodyGyro and it did not work. I have then tried using TweenService, but it obviously did not work. I then tried just applying the CFrame to the desired body parts and it did not work either. I have tried looking for similar topics and I have also searched the Roblox Devcom without any luck.

Could perhaps any of you fine people give me a hint? Thanks in advance!

15 Likes

Have you tried using

:SetPrimaryPartCFrame(CFrame.fromEularAngles or CFrame.fromOrientation)

This is the only answer I can give, because I don’t fully understand the problem, please send a video.

1 Like

No, that is not quite the thing I want to achieve. I cannot really get a video, but I am trying to make it so when you turn your character left or right, it would lean to that side.

2 Likes

Have you tried using animations

1 Like

Is this similar to what you’re envisioning?

IIRC, this was accomplished by animating the humanoid RootJoint according to a lerped value of movement on the Z axis relative to a character’s dominant movement angle.

4 Likes

Hi, is there any way you could come up with a short sample of code regarding this method? I understand how it’s accomplished but I’m not really able to figure out which property and object to lerp and how to lerp it correctly.

1 Like

Kind of like this! But is there a way i could do that without animations? If you have a simple script making the angle calculations, could you please show it?

1 Like

in the gif that @kijineko provided, it seemed like the developer made a custom character controller since there was inertia, proper incline velocity, climbing and more; not only that, but they all smoothly flowed into each other. i don’t have experience making this sort of thing, but if it’s only achievable by changing the fundamental ways player movement works, i don’t think you can accomplish it with a “simple script”

1 Like

I talked with someone more familiar with the process than me. My hypothesis was sorta correct.

in the example provided, on every frame, she used the difference between the character’s yaw on the current and last frame to check if they’re moving positively or negatively away from their current movement direction. That’s stored as 1 or -1.

From there, for interpolation weight, she determines a “rollGoal” through (1 - dot product of last frame’s vector and current frame’s vector) * 40° * movement direction. That can be used to calculate the current character tilt by lerping it with rollGoal, tilt being used transform the character’s rootJoint angles along the Z axis.

@infranova the complexity of other systems doesn’t determine the complexity of an isolated operation.

Edit: Got it implemented into a character script. Upped the tilt so it’s way more noticeable.

function Lerp(a, b, t)
	return a + (b - a) * t
end

local STEP = 0.1
local RunService = game:GetService("RunService")

function getYaw(vec)
	return -math.atan2(vec.Z, vec.X) - math.pi/2
end

local lastFrameDir = script.Parent.HumanoidRootPart.CFrame.lookVector
local lastDir = lastFrameDir
local dir = lastDir
local accum = 0

local rollGoal = 0
local roll = 0
RunService.Stepped:Connect(function(t, dt)
	accum = accum + dt
	lastFrameDir = dir
	dir = script.Parent.HumanoidRootPart.CFrame.lookVector

	local angleDiff = getYaw(dir) - getYaw(lastFrameDir)
	angleDiff = (angleDiff + math.pi/2) % math.pi - math.pi/2
	local sign = angleDiff < 0 and -1 or 1

	if accum > STEP then
		local diff = 1 - lastDir:Dot(dir)
		rollGoal = diff * math.rad(40) * sign

		lastDir = dir
		accum = 0
	end

	roll = Lerp(roll, rollGoal, 0.2)
	script.Parent.LowerTorso.Root.Transform = script.Parent.LowerTorso.Root.Transform * CFrame.Angles(0, 0, roll)
end)
28 Likes

Beautiful as all the things should be. Thank you!

1 Like

Should mention that the code I provided isn’t quite the same effect as what was shown in the tweet I shared. You might want to work on animating the character’s waist and neck joints so they have a more pronounced twist.

Anyway, wishing you good luck! Glad I could help :D

2 Likes

Thanks a ton, but does this system work with R6 if implemented with the regular torso? I’m concerned that it will weirdly snap the character’s torso and not turn the character themselves.

1 Like

Change

script.Parent.LowerTorso.Root.Transform = script.Parent.LowerTorso.Root.Transform * CFrame.Angles(0, 0, roll)

to

script.Parent.HumanoidRootPart.RootJoint.Transform = script.Parent.HumanoidRootPart.RootJoint.Transform * CFrame.Angles(0, roll, 0)

(this is the simplest way to achieve this effect. I do not advise rotating a character by its rootpart in most cases)

4 Likes