I’m making a custom character controller and my character is weirdly slippery?
Here’s an example (I’m not turning slowly on purpose, I swear)
And here’s what my code looks like
function player:MoveAndSlide()
rs.RenderStepped:Connect(function(dt)
task.desynchronize()
local factor = self.humanoid.MoveDirection * Vector3.new(self.acceleration, 0, self.acceleration) * Vector3.new(dt, 0, dt)
if self.humanoid.MoveDirection.Magnitude ~= 0 then
if self.state == 1 then
self.state = 2
end
task.synchronize()
self:Accelerate(factor)
else
if self.state == 2 then
self.state = 1
end
task.synchronize()
self:Deccelerate()
end
end)
end
function player:Accelerate(dir)
self.hrp.AssemblyLinearVelocity += dir
end
function player:Deccelerate()
self.hrp.AssemblyLinearVelocity = Vector3.new(self.hrp.AssemblyLinearVelocity.X * 0.95, self.hrp.AssemblyLinearVelocity.Y, self.hrp.AssemblyLinearVelocity.Z * 0.95)
end
I’m making a sonic game so the acceleration is a necessity, does anyone know how to fix this?
Thanks!
The slippery feeling is probably happening because you’re directly adding to AssemblyLinearVelocity every frame.
self.hrp.AssemblyLinearVelocity += dir
That keeps stacking velocity but when the player changes direction, the old horizontal velocity is still there. So the character keeps sliding in the previous direction instead of steering cleanly into the new one
for a sonic style controller, I’d separate the horizontal velocity, accelerate it toward the desired movement direction and clamp it to a max speed
Something like this
local function moveToward(current, target, maxDelta)
local delta = target - current
local distance = delta.Magnitude
if distance <= maxDelta or distance == 0 then
return target
end
return current + delta.Unit * maxDelta
end
function player:MoveAndSlide()
rs.RenderStepped:Connect(function(dt)
local velocity = self.hrp.AssemblyLinearVelocity
local horizontal = Vector3.new(velocity.X, 0, velocity.Z)
local moveDir = self.humanoid.MoveDirection
local maxSpeed = self.maxSpeed or 80
local acceleration = self.acceleration or 120
local deceleration = self.deceleration or 80
if moveDir.Magnitude > 0 then
local targetVelocity = moveDir.Unit * maxSpeed
horizontal = moveToward(horizontal, targetVelocity, acceleration * dt)
else
horizontal = moveToward(horizontal, Vector3.zero, deceleration * dt)
end
self.hrp.AssemblyLinearVelocity = Vector3.new(
horizontal.X,
velocity.Y,
horizontal.Z
)
end)
end
This still gives you acceleration but instead of endlessly adding velocity, it steers the current velocity toward the input direction
Also I’d avoid using task.desynchronize() here unless you really need it. Character physics/control code is usually easier and safer to keep synchronized