I am trying to program a movement system that modifies WalkSpeed a lot.
For a sliding mechanic in it, I wanted to make it so that while sliding, your speed would slowly decrease (by a simple linear equation) eventually to zero, until you get up at which point it resets to 16.
The issue I am having however, is with the actual movement of the sliding and that aforementioned slowdown. While the WalkSpeed does reach 0 (as evident by the print), the Humanoid:MoveTo() seems to be unaffected, even still going after the WalkSpeed hit 0.
I’m fine with redesigning it to use lerping and a tween for the hitbox instead if needed (I already had to do it for a dash system), but I just wanted to see if I was overlooking something really simple instead that’d be easier to implement.
Code:
function SLIDE()
if not sliding then
sliding = true
deact:InvokeClient(plr,false)
slidetrack:Play()
local x = 0
local cSpeed = hum.WalkSpeed
while true do -- specifically this
if sliding == false or hum.WalkSpeed <= 0 then break end
hum.WalkSpeed = (SLIDE_MULT*x)+cSpeed -- SLIDE_MULT is -0.4 if that matters
x += 1
hum:MoveTo((hrp.CFrame * CFrame.new(0,0,-8)).p)
print(hum.WalkSpeed)
wait(0.1)
end
else
slidetrack:Stop(0.5)
sliding = false
deact:InvokeClient(plr,true)
end
end
Also I apologize if there is an answer out there somewhere on here, I just couldn’t seem to find a satisfactory answer.
Humanoid:MoveTo() will perform pathfinding. Instead, you could try this. I haven’t tested it, but it should work:
function SLIDE()
local hrp = plr.Character:WaitForChild("HumanoidRootPart")
local hum = plr.Character:WaitForChild("Humanoid")
sliding = true
local slideDir = hrp.CFrame.LookVector
local startSpeed = hum.WalkSpeed
local duration = 1.5 -- seconds
local bodyVel = Instance.new("BodyVelocity")
bodyVel.MaxForce = Vector3.new(1e5, 0, 1e5)
bodyVel.Velocity = slideDir * startSpeed
bodyVel.Parent = hrp
task.spawn(function()
for t = 0, duration, 0.1 do
if not sliding then break end
local newSpeed = startSpeed * (1 - t / duration)
bodyVel.Velocity = slideDir * newSpeed
task.wait(0.1)
end
bodyVel:Destroy()
hum.WalkSpeed = 16
sliding = false
end)
end
Turns out the original problem was just me not implementing some logic correctly.
This solution however was really interesting to me since I honestly forgot that BodyVelocity existed, and that it’s honestly much better for my use case than :MoveTo (it’s just ever-so-slightly smoother)
So after a bit of tinkering, I actually managed to adapt this code to both work in mine, and have janky but technically working collision and even slope logic.
So yeah, thank you for the solution.
(also i’m like 80% sure that :MoveTo in fact has no pathfinding at all, but I could be wrong)
(also also guess i should post the code i did make here)
slopemult = 3/math.pi -- so for every 90 degrees (pi) add to the speed by 1.5, or for every degree add 0.02 (math.ceil)
function SLIDE()
if not sliding then
sliding = true
hum.AutoRotate = false
Controller(false)
slidetrack:Play()
sliding = true
local slideDir = hrp.CFrame.LookVector
local startSpeed = hum.WalkSpeed
local duration = startSpeed/12 -- simple yet effective
local bodyVel = Instance.new("BodyVelocity") -- honestly forgot that this instance existed
bodyVel.MaxForce = Vector3.new(1e5, 0, 1e5)
bodyVel.Velocity = slideDir * startSpeed
bodyVel.Parent = hrp
local notStopped = false
task.spawn(function()
for t = 0, duration, 0.1 do
if not sliding then break end
local raycheck = workspace:Raycast(hrp.Position,slideDir*2,params)
if raycheck then
if raycheck.Instance.CanCollide then
break
end
end
local slope = 1
local slopecheck = workspace:Raycast(hrp.Position,-Vector3.yAxis*10,params) -- slopes
if slopecheck then
local inst = slopecheck.Instance
if inst.CanCollide then
if inst:IsA("WedgePart") then -- im only going to use wedges
local directrad = math.atan2(inst.Size.Y,inst.Size.X) -- i luv trig <3 ; is the radians of the angle created by the wedge
if directrad < 0 or directrad > math.pi then return end -- should be impossible with correctly oriented wedges
local preslope = math.ceil(slopemult*directrad)
local rot = math.acos(slideDir:Dot(inst.CFrame.LookVector))
local ratio = rot/math.pi -- 0-1 scale with 0 being closer to 0 rads, and 1 closer to pi rads
slope = ((1-ratio*directrad)*4)-2.5
if slope < 0 then
slope = 0.5
end
end
end
end
local newSpeed = (startSpeed*slope) * (1 - t / duration)
bodyVel.Velocity = slideDir * newSpeed
task.wait(0.1)
end
bodyVel:Destroy()
hum.WalkSpeed = norm_speed
end)
else
slidetrack:Stop(0.5)
sliding = false
hum.AutoRotate = true
Controller(true)
end
end
(moved everything to a local script for smoothness)