Smooth/weighted character turning/movement?

Smooth/weighted movement?

Recently I’ve been trying to develop an R6 combat project, and I wanted to include character movement controls that felt weighted and smooth, especially when the character is turning, similar to “Bulwark” on the Experiences page on Roblox.

I am unsure of the approach that has to be taken to achieve this, since I am not sure if Roblox’s built in movement system needs to be overridden or not even to begin with, but you can easily understand what exactly I’m looking for when you join Bulwark and move around for a few seconds. If anyone has any code or can assist to achieve this goal in any way, I’d love your help! I’m stumped!

Check out the “Platformer” template in Roblox Studio, it has this mechanic built in.

See the StarterPlayer > StarterCharacterScripts > CharacterLeanScript. You can tweak the roll angle, pitch angle, and lean speed, as well as turning down walk speed if you want a slow character like in Bulwark.

--[[
	CharacterLeanScript - This script makes characters slightly lean in the direction they are moving.

	Each Step the character's Root joint Transform is updated based on the character's velocity.
--]]

local RunService = game:GetService("RunService")
local StarterPlayer = game:GetService("StarterPlayer")

-- Since this script has RunContext of Client, it will run anywhere regardless of its parent.
-- We only want it to run when it's parented to a character so we'll return immediately if it's in StarterCharacterScripts.
if script.Parent == StarterPlayer.StarterCharacterScripts then
	return
end

local character = script.Parent
-- Characters are not replicated atomically so we need to wait for children
local humanoid = character:WaitForChild("Humanoid")
local root = character:WaitForChild("HumanoidRootPart")
local rootJoint = character:WaitForChild("LowerTorso"):WaitForChild("Root")

local ROLL_ANGLE = math.rad(30)
local PITCH_ANGLE = math.rad(15)
local LEAN_SPEED = 5

local leanCFrame = CFrame.new()

local function onStepped(_: number, deltaTime: number)
	local moveVelocity = humanoid:GetMoveVelocity()
	local relativeVelocity = root.CFrame:VectorToObjectSpace(moveVelocity)

	-- Calculate pitch and roll based on the character's relative velocity
	local pitch = 0
	local roll = 0
	if humanoid.WalkSpeed ~= 0 then
		pitch = math.clamp(relativeVelocity.Z / humanoid.WalkSpeed, -1, 1) * PITCH_ANGLE
		roll = -math.clamp(relativeVelocity.X / humanoid.WalkSpeed, -1, 1) * ROLL_ANGLE
	end

	leanCFrame = leanCFrame:Lerp(CFrame.Angles(pitch, 0, roll), math.min(deltaTime * LEAN_SPEED, 1))
	-- Apply the leaning to the rootJoint's Transform
	rootJoint.Transform = leanCFrame * rootJoint.Transform
end

RunService.Stepped:Connect(onStepped)

1 Like

Thank you for the reply, and I didn’t know that this could be found in the new template maps. I will utilize this, however, I’m not sure if this is exactly what I’m looking for as far as feel.

In Bulwark, when you press “A” or “D” your character will slowly and turn into that direction while you move. In the lean script provided above, you can adjust the lean speed, however, you can’t adjust your characters turn speed, if that makes sense. I’m not really sure how to explain how it feels, but it almost feels as if there’s a drag and turning isn’t just as simple as pressing “A” and immediately turning left.

You can also tweak GROUND_ACCELERATION in ReplicatedStorage.Platformer.Constants to change the acceleration. It’s not quite a “turn speed” setting, but it does give a similar effect

1 Like

This is perfect, thank you. I just had one more question: If I wanted to port that module into another experience, what script in the game relies on that one?

The ground acceleration constant is used by the Controller:getAcceleration() method in ReplicatedStorage.Platformer.Scripts.Controller, but there’s a whole framework around that Controller script to make it work. My advice is just remove stuff you don’t need until you have a minimum set of features for what you want.

Alternatively, read the code and figure out how it works, then re-implement the parts you need yourself.

You’re right, there’s a lot here, I will see what I can do and hopefully be able to understand and re-implement those parts. Thanks you.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.