Humanoid:MoveTo() doesn't respect the humanoid's WalkSpeed?

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.

2 Likes

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

2 Likes

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)

2 Likes

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