Essentially, I’d like to create a more advanced movement system.
Currently, when you press the W key in Roblox, you instantly start moving at a set velocity. When you stop holding it, you instantly stop.
How would I make it so that the player accelerates when you start holding and reaches the maximum speed potential, and then when they release it it gradually slows down?
The system I’m trying to remake here is slightly like CS:GO’s movement system, where the player model accelerates and decelerates instead of instantly moving forward and stopping.
9 Likes
The way I implemented a movement system in my game might be interesting for you. Check it out here and tell me what you think!
https://www.roblox.com/games/6711634328/Project-Cannon
It uses ApplyImpulse() to move the character, though.
4 Likes
Yes, in fact it is something like that, would you be kind enough to tell me in more detail how you did it?
Edit: i just realised that the models in your game are just spheres so if you could tell me how to apply this to a regular playermodel that’d be great
I’ll try my best to explain it, but here’s the code:
torso:ApplyImpulse(((mathModule.fixVector(camera.CFrame.LookVector)
* (F_FORCE + B_FORCE))
+ (camera.CFrame.RightVector * (R_FORCE + L_FORCE)))
* CONST_SPEED
- ( Vector3.new(torso.Velocity.X / 2.75, torso.Velocity.Y / 3, torso.Velocity.Z / 2.75))
)
2 Likes
When W key is held, the F_FORCE is 1, else 0
When S key is held, the B_FORCE is -1, else 0
When the LookVector is multiplied by this, it gives a vector direction. I then add this to the horizontal (left/right) part using the same method and multiply it by a constant speed.
I also subtract a percentage of the current velocity from this new velocity to soft cap the speed.
Also, the reason that I have the fixVector() thing is because the LookVector can rotate anywhere, so when the character is looking directly up, there’s basically no movement forwards. So I implemented a math thing to deal with that:
function mathModule.fixVector( vector )
local angle = math.atan2(vector.Z, vector.X)
vector = Vector3.new(math.cos(angle), 0, math.sin(angle))
return vector
end
3 Likes
Capsule models will work great for this, I think. You might have to do a little bit of extra math to keep the character upright though.
System I worked on a few years ago is all about speed management. Very heavily influenced by Quake but might also have some things to help you. You are welcome to take a look and see what you can learn- I just set it to allow for copying rn. The movement is handled inside of StarterPlayer > StarterPlayerScripts > Client. You will gain speed etc based on what surface your jump lands you on as well as how much you airstrafe (although my formula is not based on anything other than mouse pos changing).
Here is the place, https://www.roblox.com/games/1108213240/RoQuake-V1-Physics-Demo
4 Likes
I’ve downloaded the place to see the movement script, you can turn copying off, many thanks.
1 Like
Sorry to bother you, but where is the R_FORCE, B_FORCE, F_FORCE, CONST_SPEED and L_FORCE values set?
I set them all at the top of the script
Also (just example, my client code is currently messy):
local function onLeft(actionName, inputState)
if inputState == Enum.UserInputState.Begin then
L_FORCE = -1
elseif inputState == Enum.UserInputState.End then
L_FORCE = 0
end
end
I set the CONST_SPEED at the top also
local CONST_SPEED = 60
local F_FORCE = 0
local R_FORCE = 0
local B_FORCE = 0
local L_FORCE = 0
1 Like
Apologies for necrobumping, but this could help new people who come to view this thread.
This is just another solution, but what I did to solve this problem was run a for loop on every basepart descendant and increase the slipperiness (decrease friction). It’s not the best option, but it does the job.
6 Likes
Try this script. I saw a deceleration script on the devforums a long time ago and combined it with a acceleration script:
local Plr = game.Players.LocalPlayer
local Char = Plr.Character or Plr.CharacterAdded:Wait()
local Hum = Char:WaitForChild("Humanoid")
local HRP = Char:WaitForChild("HumanoidRootPart")
local TS = game:GetService("TweenService")
-- configuration
local DefaultSpeed = 1
local MaxSpeed = 10
local AccelerationTime = 0.6
local DecelerationTime = 0.8
-- variables
local IsMoving = false
local AccelTween = nil
local DecelTween = nil
local DV = nil
Hum.WalkSpeed = DefaultSpeed
local function startAcceleration()
if AccelTween then
AccelTween:Cancel()
end
AccelTween = TS:Create(Hum, TweenInfo.new(AccelerationTime, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {WalkSpeed = MaxSpeed})
AccelTween:Play()
end
local function startDeceleration()
if DecelTween then
DecelTween:Cancel()
end
if DV then
DV:Destroy()
end
DV = Instance.new("BodyVelocity")
DV.MaxForce = Vector3.new(100000, 0, 100000)
DV.Velocity = HRP.Velocity
DV.Parent = HRP
DecelTween = TS:Create(Hum, TweenInfo.new(DecelerationTime, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {WalkSpeed = DefaultSpeed})
local DecelTween2 = TS:Create(DV, TweenInfo.new(DecelerationTime, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {Velocity = Vector3.new(0, 0, 0)})
DecelTween:Play()
DecelTween2:Play()
-- Destroy BodyVelocity if it still exists after deceleration
delay(DecelerationTime, function()
if DV then
DV:Destroy()
end
end)
end
Hum:GetPropertyChangedSignal("MoveDirection"):Connect(function()
if Hum.MoveDirection.Magnitude > 0 then
if not IsMoving then
IsMoving = true
startAcceleration()
end
-- If the player is moving, destroy BodyVelocity if it exists
if DV then
DV:Destroy()
DV = nil
end
else
if IsMoving then
IsMoving = false
startDeceleration()
end
end
end)
1 Like