Hey! I’ve made this movement system focused on Bhoping, but i’m having a lot of trouble with optimization. I can see a bit why this causes frame drops, but i can’t find i way to optimize it.
Any help on improving the code would be great. Even if it’s not optimization.
OBS: I sadly couldn’t comment all of the code. But for a better read i commented what every function is.
This is the code ( LocalScript at StarterCharacterScripts ):
-- local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local TS = game:GetService("TweenService")
local Library = require(workspace.SukytaPersonalModule) -- My Personal Library.
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded
local Camera = workspace.CurrentCamera
local Hum = Character:FindFirstChildOfClass("Humanoid")
local RootPart = Character:WaitForChild("HumanoidRootPart")
local State = "N/A"
local Is_Running = false
local Settings = {
-- Others.
MaxSpeed = 150, -- Caps out speed.
-- Walk.
WalkNtoMaxTime = 1.8, -- How much seconds it takes for the player to go from WalkStartSpeed to WalkSpeed / RunSpeed.
WalkStartSpeed = 6, -- Starting walkspeed.
WalkSpeed = 15, -- The walkspeed.
-- Run.
RunEnabled = true, -- Determines if player can run.
RunKey = Enum.KeyCode.LeftControl, -- Key pressed to run.
RunSpeed = 35, -- The WalkSpeed when running.
-- Slide.
SlideEnabled = false, -- Determines if player can slide.
SlideKey = Enum.KeyCode.C, -- Key pressed to slide.
-- Bhop.
BhopEnabled = false, -- Determines if player can bhop or not.
AutoBhopEnabled = true, -- Determines if the Player can just hold down the spacebar to bhop. Recommended for bhoping easier.
CapNoStrafeBhop = true, -- Determines if bhopping without strafing will have a speed limit.
BhopMaxSpeed = 60, -- Caps out the speed of bhoping without strafing.
BhopSpeedIncrement = 0, -- Brute base acceleration for bhop. Recommended: 0 - 1.
BhopAcceleration = 7.5, -- Increases the acceleration of the bhop. Acceleration increases with bhop. Recommended: 5 - 25
BhopHorizontalConvertPercentage = 5, -- Determines how much of Horizontal speed will be converted to vertical speed when landing. Max: 100
-- Air.
AirEnabled = false, -- Determines if air is enabled or not. Staying at air won't affect your speed. --> Strafe will continue working even if this is off.
AirAcceleration = 2.5, -- Determines how fast you accelerate at air. Recommended: 1 - 3.5. !!! Affects bhoping heavily !!!
-- Strafe.
StrafeEnabled = false, -- Determines if strafe will be enabled or not. !!! If strafe is not enabled, deactivate CapNoStrafeBhop !!!
StrafeAcceleration = 15, -- Increases base strafe acceleration. Recommended: 7.5 - 20.
StrafeStrength = 15, -- Increases overall strafe speed increase. Recommended: 5 - 20.
StrafeSensitivity = 2.1, -- Increases how much you need to move your camera for strafe to work. Recommended: 2 - 3.
-- Camera.
CameraFirstPerson = false, -- Determines if camera will be locked at first person. !!! Turning this off will turn strafe off ( cus strafe only works with first person ) !!! Imagine being bad at scripting.
CameraSwayEnabled = false, -- Determines if camera will have a sway when moved. If not at first person this may bug your camera.
CameraSwayStrength = 2.4, -- Determines how strong sway is. Recommended: 2 - 4.
SpeedAffectsFov = true, -- Determines if speed affects camera Fov.
CameraBaseFov = 70, -- Normal camera Fov. Recommended: 70 - 80.
CameraMaxFov = 120, -- Caps out the Camera Fov. Recommended: 110 - 120.
CameraOffset = Vector3.new(0, 0.5, -1), -- Determines the camera offset. --> Won't affect camera if first person is not enabled.
CameraFovSensitivity = 6 -- Changes how much Fov will be affected by speed. --> Minimum: 0 | Maximum: 10 | Recommended: 4 - 6.
}
---------------------------------- Putting invalid values or values out of the min-max range will cause errors!
---------------------------------- Having really low BhopAcceleration may cause bhop to be useless!
Camera.FieldOfView = Settings.CameraBaseFov
if Settings.CameraFirstPerson == true then Player.CameraMode = Enum.CameraMode.LockFirstPerson else Player.CameraMode = Enum.CameraMode.Classic end
if Settings.CameraFirstPerson == true then Hum.CameraOffset = Settings.CameraOffset end
local Tween = TS:Create(Hum, TweenInfo.new(Settings.WalkNtoMaxTime, Enum.EasingStyle.Cubic, Enum.EasingDirection.In), {WalkSpeed = Settings.WalkSpeed})
local BaseWalkSpeed = Settings.WalkSpeed
local NextSpeed = 0
local AirSpeed = 0
local Chain = 0 -- Bhop Chain --> Can be used to grant points or just as a stat.
local Turn = 0
local BhopResetTime = if Settings.AutoBhopEnabled == true then 0.02 else 0.085
-------------------------- Helping Functions --------------------------
local function Flatten(vec: Vector3): Vector2
return Vector2.new(vec.X, vec.Z).Unit
end
local LastDirection = Flatten(Camera.CFrame.LookVector)
local Lerp = function(a, b, t)
return a + (b - a) * t
end;
-------------------------- Movement Code --------------------------
Hum.StateChanged:Connect(function(_, NewState: Enum.HumanoidStateType) -- Resetting bhop after landing.
if NewState == Enum.HumanoidStateType.Landed then
local function A()
if Hum.FloorMaterial ~= Enum.Material.Air then
task.wait(0.1)
if Hum.FloorMaterial ~= Enum.Material.Air then
task.wait(BhopResetTime)
if Hum.FloorMaterial ~= Enum.Material.Air then
local NewTween = TS:Create(Hum, TweenInfo.new(0.1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out, 0, false, 0), {WalkSpeed = BaseWalkSpeed})
local NewTween2 = TS:Create(Camera, TweenInfo.new(0.75, Enum.EasingStyle.Quart, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = Settings.CameraBaseFov})
NewTween:Play()
NewTween2:Play()
task.wait(0.11)
Hum.WalkSpeed = BaseWalkSpeed
Chain = 0
State = "N/A"
end
end
return
end
end
coroutine.wrap(A)()
end
end)
local function AutoBhop(IsJumping) -- Auto Bhop.
if Settings.BhopEnabled == false then return end
if Hum.FloorMaterial == Enum.Material.Air then return end
if IsJumping then
local Success = pcall(function()
State = "Bhoping"
if Hum.WalkSpeed < Settings.MaxSpeed then
if AirSpeed > 0 then AirSpeed -= (20 / 100) * AirSpeed end
if Hum.WalkSpeed < Settings.BhopMaxSpeed + AirSpeed or Settings.CapNoStrafeBhop == false then
NextSpeed = ((1.6 - (1.6 / (100 - Settings.BhopAcceleration))) * (Hum.WalkSpeed / 1.5)) - math.log(Hum.WalkSpeed, 4.5)
if Is_Running == true then NextSpeed *= 1.1 end
NextSpeed += Settings.BhopSpeedIncrement
NextSpeed += AirSpeed
elseif Hum.WalkSpeed > Settings.BhopMaxSpeed + AirSpeed and Settings.CapNoStrafeBhop == true then
NextSpeed = Settings.BhopMaxSpeed + AirSpeed
end
if NextSpeed > Settings.BhopMaxSpeed + AirSpeed then NextSpeed = Settings.BhopMaxSpeed + AirSpeed end
if NextSpeed > Settings.MaxSpeed then NextSpeed = Settings.MaxSpeed - (1 + AirSpeed + 1) end
if RootPart.Velocity.Y < -15 then
NextSpeed += (Settings.BhopHorizontalConvertPercentage / 100) * -RootPart.Velocity.Y -- Converter.
task.wait()
RootPart.Velocity.Y = 1
end
Chain += 1
local BhopTween = TS:Create(Hum, TweenInfo.new(0.15, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0), {WalkSpeed = NextSpeed})
BhopTween:Play()
if Settings.SpeedAffectsFov == true then
local NewTween = TS:Create(Camera, TweenInfo.new(0.1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = Settings.CameraBaseFov + Hum.WalkSpeed / (10 - Settings.CameraFovSensitivity)})
NewTween:Play()
end
else
Hum.WalkSpeed = Settings.MaxSpeed
end
end)
end
end
local function ManualBhop(Input, Processed) -- Manual Bhop
if Settings.BhopEnabled == false then return end
if Hum.FloorMaterial == Enum.Material.Air then return end
if Processed == true then return end
if Input.UserInputType ~= Enum.UserInputType.Keyboard then return end
if Input.KeyCode ~= Enum.KeyCode.Space then return end
if Settings.BhopEnabled == false then return end
local Success = pcall(function()
State = "Bhoping"
if Hum.WalkSpeed < Settings.MaxSpeed then
if AirSpeed > 0 then AirSpeed -= (20 / 100) * AirSpeed end
if Hum.WalkSpeed < Settings.BhopMaxSpeed + AirSpeed or Settings.CapNoStrafeBhop == false then
NextSpeed = ((1.6 - (1.6 / (100 - Settings.BhopAcceleration))) * (Hum.WalkSpeed / 1.5)) - math.log(Hum.WalkSpeed, 4.5)
if Is_Running == true then NextSpeed *= 1.1 end
NextSpeed += Settings.BhopSpeedIncrement
NextSpeed += AirSpeed
elseif Hum.WalkSpeed > Settings.BhopMaxSpeed + AirSpeed and Settings.CapNoStrafeBhop == true then
NextSpeed = Settings.BhopMaxSpeed + AirSpeed
end
if NextSpeed > Settings.BhopMaxSpeed + AirSpeed then NextSpeed = Settings.BhopMaxSpeed + AirSpeed end
if NextSpeed > Settings.MaxSpeed then NextSpeed = Settings.MaxSpeed - (1 + AirSpeed + 1) end
if RootPart.Velocity.Y < -15 then
NextSpeed += (Settings.BhopHorizontalConvertPercentage / 100) * -RootPart.Velocity.Y -- Converter.
task.wait()
RootPart.Velocity.Y = 1
end
local BhopTween = TS:Create(Hum, TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0), {WalkSpeed = NextSpeed})
BhopTween:Play()
if Settings.SpeedAffectsFov == true then
local NewTween = TS:Create(Camera, TweenInfo.new(0.1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = Settings.CameraBaseFov + Hum.WalkSpeed / (10 - Settings.CameraFovSensitivity)})
NewTween:Play()
end
else
Hum.WalkSpeed = Settings.MaxSpeed
end
end)
end
local function Strafe() -- Strafe.
if Settings.StrafeEnabled == true then return end
if Hum.FloorMaterial ~= Enum.Material.Air then return end
--[[
Strafe gives speed based on how much player moved his camera.
]]
local Direction = Flatten(Camera.CFrame.LookVector)
local Angle = math.asin(LastDirection:Cross(Direction))
if Angle ~= 0 and Library.NumbersMagnitude(Angle, 0) > (Settings.StrafeSensitivity / 50) and Library.NumbersMagnitude(Angle, 0) < Settings.StrafeSensitivity * 2.5 then
local NewAirSpeed = ((Settings.StrafeAcceleration / (2 - (Settings.StrafeStrength / 100))) / math.log(Hum.WalkSpeed, 11)) + Library.TurnPositive(Angle)
NewAirSpeed = (Settings.StrafeStrength / 100) * NewAirSpeed
if Hum.WalkSpeed + NewAirSpeed > Settings.MaxSpeed then NewAirSpeed = 0 end
AirSpeed += NewAirSpeed
Hum.WalkSpeed += NewAirSpeed
elseif Library.NumbersMagnitude(Angle, 0) > 5 then
local NewAirSpeed = -(((Settings.StrafeAcceleration / 15) / math.log(Hum.WalkSpeed, 13)) - Library.TurnPositive(Angle)) - Settings.StrafeStrength
AirSpeed += NewAirSpeed
Hum.WalkSpeed += NewAirSpeed
end
LastDirection = Direction
end
local function Sway(DT)
local MouseDelta = UIS:GetMouseDelta()
Turn = Lerp(Turn, math.clamp(MouseDelta.X, -Settings.CameraSwayStrength, Settings.CameraSwayStrength), (Settings.CameraSwayStrength * DT))
Camera.CFrame = Camera.CFrame * CFrame.Angles(0, 0, math.rad(Turn))
end
if Settings.StrafeEnabled == true then
Hum:GetPropertyChangedSignal("MoveDirection"):Connect(function()
if State ~= "Bhoping" and Hum.FloorMaterial ~= Enum.Material.Air then return end
if math.round(Hum.MoveDirection.X) == -1 then
local NewAirSpeed = ((Settings.AirAcceleration / 1.5) / math.log(Hum.WalkSpeed, 11))
if Hum.WalkSpeed + NewAirSpeed > Settings.MaxSpeed then NewAirSpeed = Settings.MaxSpeed - Hum.WalkSpeed end
AirSpeed += NewAirSpeed
Hum.WalkSpeed += NewAirSpeed
elseif math.round(Hum.MoveDirection.X) == 1 then
local NewAirSpeed = ((Settings.AirAcceleration / 1.5) / math.log(Hum.WalkSpeed, 11))
if Hum.WalkSpeed + NewAirSpeed > Settings.MaxSpeed then NewAirSpeed = Settings.MaxSpeed - Hum.WalkSpeed end
AirSpeed += NewAirSpeed
Hum.WalkSpeed += NewAirSpeed
elseif Hum.MoveDirection == Vector3.new(0, 0, 0) and AirSpeed > 0 then
local NewAirSpeed = (7.5 / 100) * AirSpeed
AirSpeed -= NewAirSpeed
Hum.WalkSpeed -= NewAirSpeed
end
end)
end
if Settings.AirEnabled == true then
Hum:GetPropertyChangedSignal("FloorMaterial"):Connect(function() -- Air Acceleration.
if Hum.FloorMaterial == Enum.Material.Air then
local LastChain = Chain
task.wait(0.5)
if Hum.FloorMaterial ~= Enum.Material.Air then return end
repeat
local NewAirSpeed = (Settings.AirAcceleration / math.log(Hum.WalkSpeed, 8)) * 1.25
if Hum.WalkSpeed + NewAirSpeed > Settings.MaxSpeed then NewAirSpeed = Settings.MaxSpeed - Hum.WalkSpeed end
AirSpeed += NewAirSpeed
Hum.WalkSpeed += NewAirSpeed
RS.Heartbeat:Wait()
until Hum.FloorMaterial ~= Enum.Material.Air
task.wait(0.15)
if Hum.FloorMaterial ~= Enum.Material.Air and Chain <= LastChain then AirSpeed = 0 return end
repeat wait(0.1) until State ~= "Bhoping"
AirSpeed = 0
end
end)
end
Hum:GetPropertyChangedSignal("MoveDirection"):Connect(function() -- Walk Acceleration.
if State == "Bhoping" or Hum.FloorMaterial == Enum.Material.Air then return end
if Hum.MoveDirection == Vector3.new(0,0,0) then
Hum.WalkSpeed = Settings.WalkStartSpeed
if Tween then
Tween:Cancel()
end
Tween = nil
elseif not Tween then
Tween = TS:Create(Hum, TweenInfo.new(Settings.WalkNtoMaxTime, Enum.EasingStyle.Sine, Enum.EasingDirection.In), {WalkSpeed = BaseWalkSpeed})
Tween:Play()
end
end)
if Settings.RunEnabled == true or Settings.SlideEnabled == true then
UIS.InputBegan:Connect(function(Input, Processed) -- Run
if Processed == true then return end
if Input.UserInputType ~= Enum.UserInputType.Keyboard then return end
if Input.KeyCode == Settings.RunKey and Settings.RunEnabled == true then
Is_Running = not Is_Running
task.wait()
if Is_Running == false then
BaseWalkSpeed = Settings.WalkSpeed
task.wait()
if State ~= "Bhoping" and Hum.FloorMaterial ~= Enum.Material.Air then -- Sees if player is bhoping
local WalkTween = TS:Create(Hum, TweenInfo.new(1.2, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out, 0, false, 0), {WalkSpeed = Settings.WalkSpeed})
WalkTween:Play()
end
else
BaseWalkSpeed = Settings.RunSpeed
task.wait()
if State ~= "Bhoping" and Hum.FloorMaterial ~= Enum.Material.Air then
local RunTween = TS:Create(Hum, TweenInfo.new(1.2, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out, 0, false, 0), {WalkSpeed = Settings.RunSpeed})
RunTween:Play()
end
end
wait(1.5)
elseif Input.KeyCode == Settings.SlideKey and Settings.SlideEnabled == true then
print("Slide!") -- I did not make it yet.
end
end)
end
-------------------------- Connections --------------------------
if Settings.BhopEnabled == true then
local BhopConnection = if Settings.AutoBhopEnabled == true then Hum.Jumping:Connect(AutoBhop) else UIS.InputBegan:Connect(ManualBhop)
end
if Settings.StrafeEnabled == true and Settings.CameraFirstPerson == true then
RS:BindToRenderStep("UpdateCamera", Enum.RenderPriority.Camera.Value + 1, Strafe)
end
if Settings.CameraSwayEnabled == true then
RS:BindToRenderStep("SwayCamera", Enum.RenderPriority.Camera.Value + 2, Sway)
end
Also, most equations in this code, such as the equation for adding speed after bhoping, are basically random, meaning i came up with them by just putting some random things here and there until i found a decent result. If you have a better way in mind, i would be grateful if you could say it.
The “Library” used in the code is a Personal Module i made in the mean time, all the functions used in this code are really simple functions, but if you need the code from it, i will reply with it.