I am playing with custom logic to move a humanoid player and for some reason it cannot move at any speed beyond a crawl along the x and z axes. But if I run diagonal to those directions I can reach the correct full speed. Currently I set the humanoid’s walkspeed to 0.1 (slow enough not to meaningfully interfere but not 0 so that the humanoid rotates as keys are pressed normally) and a BodyVelocity which is a child of the humanoid root part pushes the player around. In the video you can see a short demonstration. I turned down the tightness and friction of the controls a bunch to better demonstrate what is going on.
Notice how the rounded velocity of the root part and the BodyVelocity which are printed in the output drift apart while traveling along the problematic axes. And it only happens on the ground. When I start jumping it works pretty fine. It also works great when I am in the air with that hover debug button.
Anyone else done anything like this before? I think it is clear the humanoid is interfering with the movement code, but I am clueless as to how to fix the movement without removing the player from the running state.
EDIT: added code
local function Update(dt)
--Get the wish direction
local input = control:GetMoveVector();
local dirMapper = CFrame.new(hrp.CFrame.Position, hrp.CFrame.Position + (CAMERA.CFrame.LookVector * Vector3.new(1, 0, 1)));
input = input:Dot(input) > 0 and input.unit or input;
input = dirMapper:VectorToWorldSpace(input);
--Detect if player is grounded
if Humanoid:GetState() == Enum.HumanoidStateType.Running or Humanoid:GetState() == Enum.HumanoidStateType.RunningNoPhysics then
--print("Groundmove");
local newvel = MoveGround(input, Vector3.new(hrp.Velocity.X, 0, hrp.Velocity.Z), dt);
bodyVel.Velocity = newvel;
elseif Humanoid:GetState() == Enum.HumanoidStateType.Freefall or Humanoid:GetState() == Enum.HumanoidStateType.Jumping or Humanoid:GetState() == Enum.HumanoidStateType.Landed then
--print("Airmove");
local newvel = MoveGround(input, Vector3.new(hrp.Velocity.X, 0, hrp.Velocity.Z), dt);
bodyVel.Velocity = newvel;
end
local spd = Vector3.new(hrp.Velocity.X, 0, hrp.Velocity.Z).Magnitude
local spd2 = Vector3.new(bodyVel.Velocity.X, 0, bodyVel.Velocity.Z).Magnitude
print("hrpSpeed: " .. math.floor(spd + 0.5), " bodyVelocitySpeed: " .. math.floor(spd2 + 0.5));
end
game:GetService("RunService"):BindToRenderStep("MoveControl", Enum.RenderPriority.Input.Value, function(dt)
Update(dt);
end)
Reason why it might be slower on the ground is because the way gravity works.
Gravity is pulling you downwards, which can cause a noticable drop like that. The default Roblox movement system counters that, but yours is custom and probably didn’t account for that.
Thats why it drops on the ground.
So try working around gravity and see if that’ll help.
The controller should be accounting for gravity correctly. It completely ignores the Y value of the velocities for now and lets the humanoid be in charge of falling and jumping normally.
EDIT: I just added the code for the main loop to the post.
The “easy” way to fix it is to just increase the velocity of the player on the ground but, I don’t think that’d be so reliable.
You might need to make a switch from Humanoid to your own scripts. Letting the Humanoid control falling will also take gravity to it and thats probably what the issue is.
If I set the player’s state to physics or platformstanding then it will slide around correctly. I think it has less to do with the gravity and more to do with the running state and the walk speed.
Not using the humanoid is what I have done in the past and it is kinda miserable having to recreate every function of the humanoid that I need to use. Right now I am trying to focus everything into pushing the humanoid as far as I can.
You might want to just increase the WalkSpeed then, thats the easy way out of it.
if Humanoid:GetState() == Enum.HumanoidStateType.Running or Humanoid:GetState() == Enum.HumanoidStateType.RunningNoPhysics then
--print("Groundmove");
local newvel = MoveGround(input, Vector3.new(hrp.Velocity.X, 0, hrp.Velocity.Z), dt);
bodyVel.Velocity = newvel;
elseif Humanoid:GetState() == Enum.HumanoidStateType.Freefall or Humanoid:GetState() == Enum.HumanoidStateType.Jumping or Humanoid:GetState() == Enum.HumanoidStateType.Landed then
--print("Airmove");
local newvel = MoveGround(input, Vector3.new(hrp.Velocity.X, 0, hrp.Velocity.Z), dt);
bodyVel.Velocity = newvel;
end
You have this, which you can make a MoveAir function so you can set the WalkSpeed to what it is now and have the MoveGround function have the increased WalkSpeed.
Yes. If you would like more information I can post more of the code. Just let me know what you want to see. In the video you can see in the output that the speed for the bodyvelocity is correct, but the humanoid root part only goes up to 4 or so on the x and z axes. They are printed side by side as the code runs.
Unfortunately I cannot use walkspeed because the way I do math on the movement vectors in the MoveGround and MoveAir functions defines the feel of the style of movement I am recreating.
Using the humanoid’s build in walk speed does not allow player needs to carry momentum when no keys are pressed.
As a side note, the MoveAir function actually already exists. I have MoveGround where it usually would be in order to test what the MoveGround does while the player is in the Freefall, Jumping, and Landed states.
I think I can prove it is not the gravity. I used that hover button I used in the video which counteracts the pull of gravity and prevents the player from falling while standing on the ground. I did not exit the running state and the x and z axis issue was unaffected.
Sorry for the short and conclusive answers; I would’ve went into more depth and such into fixing the issue but I’m about to go to bed as I am very tired.
Using a custom humanoid is against my self imposed challenge.
Setting my walkspeed higher will also increase the speed while traveling in the directions that work correctly.
In my testing the speed of the player along the x and z axes seems to be related to the humanoids walkspeed. If i turn it up to one then the slow speed goes up to 5 while the correct speed in the diagonals remains the same.