Hello, I’m trying to remake air strafing for a game, I’m mainly using this code, as i’ve seen in other posts, but when I tried to remake it, it just sent me flying extremely fast out of the baseplate. Localscript:
local serverVars = {
airacceleration = 10;
maxacceleration = 60;
friction = 1
}
local accelDir = Vector3.new(0,0,0)
local playerVelocity = Vector3.new(0,0,0)
local prevVelocity = Vector3.new(0,0,0)
local function onGround()
local checkRay = Ray.new(Char:GetPrimaryPartCFrame().p, Vector3.new(0,-6,0))
local hit,pos,normal = workspace:FindPartOnRay(checkRay, Char)
if hit ~= nil then
return true
end
return false
end
local function accelerate(Direction, prevVelocity, DeltaTime)
local projection = prevVelocity:Dot(Direction) -- problem is probably here
local acceleration = serverVars.airacceleration * DeltaTime
print(acceleration, projection)
if (projection + acceleration > serverVars.maxacceleration) then
acceleration = serverVars.maxacceleration-projection
elseif (projection + acceleration < -serverVars.maxacceleration) then
acceleration = serverVars.maxacceleration+projection
end
return prevVelocity + Direction * acceleration
end
local function groundMove(Direction, prevVelocity, DeltaTime)
local speed = prevVelocity.magnitude
if speed ~= 0 and onGround() then
local drop = speed * 1 * DeltaTime
prevVelocity = prevVelocity * math.max(speed - drop, 0) / speed
end
return accelerate(Direction, prevVelocity, DeltaTime)
end
local Time = tick()
function updateAirStrafe(DeltaTime)
if w then -- defined later on code with UserInputService
accelDir = accelDir + Vector3.new(1,0,0)
end
if s then -- defined later on code with UserInputService
accelDir = accelDir + Vector3.new(-1,0,0)
end
if a then -- defined later on code with UserInputService
accelDir = accelDir + Vector3.new(0,0,1)
end
if d then -- defined later on code with UserInputService
accelDir = accelDir + Vector3.new(0,0,-1)
end
if not onGround() then
playerVelocity = accelerate(accelDir, playerVelocity, DeltaTime)
prevVelocity = playerVelocity
local posDelta = bodyvelocity.Velocity + playerVelocity
print(posDelta)
Char.HumanoidRootPart.Velocity = posDelta+Vector3.new(0,3,0)
end
end
spawn(function()
game:GetService("RunService").RenderStepped:Connect(function()
local t = tick()
local dt = t - Time
Time = t
updateAirStrafe(dt)
end)
end)
tl;dr Help me fix bhop script up here
4 Likes
I think all you have to do is redefine accelDir every time you use the updateAirStrafe function:
function updateAirStrafe(DeltaTime)
--add this part here
accelDir = Vector3.new()
--continue on with the rest of the function
Since you are using it in a RunService loop, accelDir will just keep adding to itself without ever reseting. Dot products also factor in magnitude, so prevVelocity:Dot(Direction) will increase/decrease per frame from Direction's magnitude. It might be helpful to use prevVelocity:Dot(Direction.Unit) as well, it depends.
2 Likes
New issue, I’m just floating up forever…
local serverVars = {
airacceleration = 10;
maxacceleration = 60;
friction = 1
}
local accelDir = Vector3.new(0,0,0)
local playerVelocity = Vector3.new(0,0,0)
local prevVelocity = Vector3.new(0,0,0)
local function onGround()
local checkRay = Ray.new(Char:GetPrimaryPartCFrame().p, Vector3.new(0,-6,0))
local hit,pos,normal = workspace:FindPartOnRay(checkRay, Char)
if hit ~= nil then
return true
end
return false
end
local function accelerate(Direction, prevVelocity, DeltaTime)
local projection = prevVelocity:Dot(Direction.Unit)
local acceleration = serverVars.airacceleration * DeltaTime
print(acceleration, projection)
if (projection + acceleration > serverVars.maxacceleration) then
acceleration = serverVars.maxacceleration-projection
elseif (projection + acceleration < -serverVars.maxacceleration) then
acceleration = serverVars.maxacceleration+projection
end
return prevVelocity + Direction * acceleration
end
local function groundMove(Direction, prevVelocity, DeltaTime)
local speed = prevVelocity.magnitude
if speed ~= 0 and onGround() then
local drop = speed * 1 * DeltaTime
prevVelocity = prevVelocity * math.max(speed - drop, 0) / speed
end
return accelerate(Direction, prevVelocity, DeltaTime)
end
local Time = tick()
function updateAirStrafe(DeltaTime)
if w then
accelDir = accelDir + Vector3.new(1,0,0)
end
if s then
accelDir = accelDir + Vector3.new(-1,0,0)
end
if a then
accelDir = accelDir + Vector3.new(0,0,1)
end
if d then
accelDir = accelDir + Vector3.new(0,0,-1)
end
if not onGround() then
playerVelocity = accelerate(accelDir, playerVelocity, DeltaTime)
playerVelocity = playerVelocity + (Vector3.new(0,workspace.Gravity,0) * DeltaTime)
prevVelocity = playerVelocity
local posDelta = bodyvelocity.Velocity + playerVelocity
print(posDelta)
Char.HumanoidRootPart.Velocity = posDelta+Vector3.new(0,3,0)
end
end
spawn(function()
game:GetService("RunService").RenderStepped:Connect(function()
local t = tick()
local dt = t - Time
Time = t
accelDir = Vector3.new()
playerVelocity = Vector3.new(0,0,0)
prevVelocity = Vector3.new(0,0,0)
updateAirStrafe(dt)
end)
end)
1 Like
So just as a very quick optimization, though this won’t solve your problem, RunService.RenderStepped returns the amount of time since the last step, so you could very easily remove t and Time and place dt in the function argument:
spawn(function()
game:GetService("RunService").RenderStepped:Connect(function(dt)
accelDir = Vector3.new()
--etc
Also, I don’t think you need to reset playerVelocity and prevVelocity every step, or at least I don’t think it’s the solution.
The problem may also be coming from setting Char.HumanoidRootPart.Velocity with an offset of (0,3,0) every frame in the updateAirStrafe function, try removing it and see what happens.
5 Likes
Thanks, now I only gotta fix the problem of velocity not resetting when I jump second time, other than that all is fine!
1 Like