I’ve tried making my own character controller but it had so many problems and wasn’t rewarding enough to deal with.
So that’s why I need to make a character controller that has smooth movement, such as deceleration, acceleration and momentum. (bunny-hopping not needed)
Throughout the process, I’ve checked several sources that explain Quake’s movement, though I just couldn’t understand most of them. If there are any examples that you can provide with code, it would be incredibly helpful. Thank you.
Have you ever tried looking at the source code directly? I’m currently working on a Roblox port of bhop/surf and I’ve been referencing the code directly from source engine to recreate the strafe movements.
I did an extremely basic version of something like this. It’s just a ControlScript that uses springs to control your direction movement vector. The springs are carefully tuned so that they don’t bounce, but they have acceleration and deceleration, making character movement more smooth at the cost of being slightly less responsive.
You can find a toned down version of this used in @thisfall’s latest 3 showcases, if you’d like to try it out to see what I mean.
These seem like they might be just what I’m looking for. By doing a little configuration, it could possibly look like Quake’s movement. Are there any bugs with it though? (character getting flung when it collides with another object etc.)
I would be extremely thankful if you could tell me the procedure.
It uses the default humanoid features, so if there are any flinging bugs, that’s on Roblox, not me. I’ve never encountered any issues with it (yet).
It’s pretty simple. You have a Vector3 spring (there are tons of great modules for this, I used Quenty’s) and alter the spring’s target when movement keys are pressed/depressed. Use the spring as your movement vector, and you’re done!
Simple demo:
local UIS,RS = game:GetService("UserInputService"), game:GetService("RunService")
local Spring = require(script.SpringModule)
local v3 = Vector3.new
local Direction = Spring.new(v3())
Direction.Speed = 8
local Front,Side = v3(0,0,1),v3(1,0,0)
local LastJump,JUMP_COOLDOWN = 0,1.4
UIS.InputBegan:Connect(function(Input,GP)
if not GP and Input.UserInputType == Enum.UserInputType.Keyboard then
--Handle movement
if Input.KeyCode == Enum.KeyCode.W then
Direction.Target = Direction.Target - Front
elseif Input.KeyCode == Enum.KeyCode.S then
Direction.Target = Direction.Target + Front
elseif Input.KeyCode == Enum.KeyCode.A then
Direction.Target = Direction.Target - Side
elseif Input.KeyCode == Enum.KeyCode.D then
Direction.Target = Direction.Target + Side
--Handle jumping
elseif Input.KeyCode == Enum.KeyCode.Space then
if tick()-LastJump>= JUMP_COOLDOWN then
Humanoid.Jump = true
LastJump = tick()
end
end
end
end)
UIS.InputEnded:Connect(function(Input,GP)
if not GP and Input.UserInputType == Enum.UserInputType.Keyboard then
--Handle movement
if Input.KeyCode == Enum.KeyCode.W then
Direction.Target = Direction.Target + Front
elseif Input.KeyCode == Enum.KeyCode.S then
Direction.Target = Direction.Target - Front
elseif Input.KeyCode == Enum.KeyCode.A then
Direction.Target = Direction.Target + Side
elseif Input.KeyCode == Enum.KeyCode.D then
Direction.Target = Direction.Target - Side
end
end
end)
RS:BindToRenderStep("Walking", 100, function()
Player:Move(Direction.Position, true)
end)