Help improve movement (dash, jump, and run)

Movement - Code Review.rbxl (37.8 KB)

Provide an overview of:
I want to make the code faster safer and try to complete unnecessary goals (in comments)

local script in StarterCharacterScripts:

local UIS = game:GetService("UserInputService")
local CS = game:GetService("CollectionService")

local camera = workspace.CurrentCamera
local plr = game:GetService("Players").LocalPlayer
local RunSetting = plr:WaitForChild("Settings").ToggleRun

local runEvent = game:GetService("ReplicatedStorage").Stamina

local character = script.Parent
local hum:Humanoid = character:WaitForChild("Humanoid")
local animator:Animator = hum:WaitForChild("Animator")

local run_anim = animator:LoadAnimation(script.Parent.anim.Run)
local jump_anim = animator:LoadAnimation(script.Parent.anim.Jump)
local dash_anim = animator:LoadAnimation(script.Parent.anim.Dash)

local Stamina = plr:WaitForChild("leaderstats"):WaitForChild("Stamina")
local MaxStamina = 100

local isRunning = false
local HoldingWeapon = false

local runDB = false
local jumpDB = false
local dashDB = false

local connections = {}


function tweencamera(t)
	local direction = (t and 1) or -1 --//(if true then dirction = 1 else direnction = -1)
	t = (t and 85) or 70 --//(if true then goal = 85 else goal = 70(default))
	for i = camera.FieldOfView, t, direction do
		task.wait(0.01)
		camera.FieldOfView = i
	end
end


local function StopSprint()
	hum.WalkSpeed = 16
	run_anim:Stop()
	tweencamera(false)
	isRunning = false
	connections.Movement:Disconnect() --//Sometimes gives me errors but code still works fine
	connections.Movement = nil
	task.wait(0.3)
	runEvent:FireServer(false)
	runDB = true
	task.wait(0.2)
	runDB = false
end

local function Sprint()
	hum.WalkSpeed = 24
	isRunning = true
	run_anim:Play(0.5, 5)
	tweencamera(true)
	runEvent:FireServer(true)
end


UIS.InputBegan:Connect(function(input, GPE)
	if GPE or Stamina.Value <= 9 then return end
	if input.KeyCode == Enum.KeyCode.LeftShift and hum.MoveDirection.Magnitude >= 1 then
		if hum:GetState() == Enum.HumanoidStateType.Jumping or runDB or HoldingWeapon then return end
		if isRunning and RunSetting.Value then
			StopSprint()
		else
			Sprint()
			connections.Movement = hum.Changed:Connect(function(property) --//stops sprinting if player isn't moving
				if property == "MoveDirection" and hum.MoveDirection.Magnitude == 0 then
					StopSprint()
				end
			end)
		end
	elseif input.KeyCode == Enum.KeyCode.Q then
		if hum.MoveDirection.Magnitude == 0 or dashDB then return end --//would be nice if I could make it so they can only dash forward
		dashDB = true
		runEvent:FireServer(nil, 15)
		dash_anim:Play()
		task.wait(1)
		dashDB = false
	end
end)


UIS.InputEnded:Connect(function(input, GPE)
	if GPE or RunSetting.Value then return end
	if input.KeyCode == Enum.KeyCode.LeftShift then
		StopSprint()
	end
end)

UIS.JumpRequest:Connect(function()
	if jumpDB or HoldingWeapon or isRunning then
		hum:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
	else
		hum:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
		jumpDB = true
		jump_anim:Play()
		runEvent:FireServer(nil, 10)
		jump_anim.Stopped:Wait()
		task.wait(0.4)
		jumpDB = false
	end
end)

character.ChildAdded:Connect(function(child)
	if CS:HasTag(child, "Weapon") then
		HoldingWeapon = true
		if isRunning then
			StopSprint()
		end
	end
end)

character.ChildRemoved:Connect(function(child)
	if CS:HasTag(child, "Weapon") then
		HoldingWeapon = false
	end
end)


-----------------------------------Old stamina stuff-----------------------------------
--[[game:GetService("RunService").RenderStepped:Connect(function()
	if isRunning and Stamina.Value <= 0 then
		StopSprint()
	elseif not isRunning and Stamina.Value < MaxStamina then
		if StaminaRegenDB == false then
			task.wait(0.2)
			Stamina.Value += 0.1
		end
	elseif isRunning and Stamina.Value > 0 then
		task.wait(0.1)
		Stamina.Value -= 0.1
	end
	Stamina.Value = (Stamina.Value < 0 and 0 or Stamina.Value > MaxStamina and MaxStamina) or Stamina.Value
end)]]

Server Script in ServerScriptService:

local plrs = game:GetService("Players")

local Event = game:GetService("ReplicatedStorage").Stamina

local runningPs = {}
local staminaRegenDB = {}

Event.OnServerEvent:Connect(function(plr, t, remove)
	runningPs[plr.Name] = (t and true) or nil
	plr.leaderstats.Stamina.Value -= math.abs(remove or 0)
	staminaRegenDB[plr.Name] = (t and true or remove and true) or nil
	coroutine.wrap(function() --//trying to make it so they don't regen immediatly not sure if it works
		task.wait(0.3)
		staminaRegenDB[plr.Name] = nil
	end)
end)


game:GetService("RunService").Heartbeat:Connect(function()
	for i, v in ipairs(plrs:GetChildren()) do
		if runningPs[v.Name] then
			task.wait(0.1)
			v.leaderstats.Stamina.Value -= 0.1
		else
			if v.leaderstats.Stamina.Value < 100 then
				if staminaRegenDB[v.Name] then return end
				task.wait(0.2)
				v.leaderstats.Stamina.Value += 0.1
			end
		end
		v.leaderstats.Stamina.Value = math.clamp(v.leaderstats.Stamina.Value, 0, 100) --//make sure stamina doesn't go above or below limits
	end
end)
2 Likes

btw in the rblx file the StaminaValue script is not how I actually make it it’s just faster to write because I didn’t want to put the entire playeradded script

I found out how to male the dash forward only thing but I still need to fix some bigs should I post it on #help-and-feedback:scripting-support?

The only thing I can advise is to remove some of the code on the server and implement it on the client. It doesn’t make sense to do stamina logic on the server, it even has a negative impact on performance to some extent, because WalkSpeed is a client-dependent property, and as we know, cheater players can easily replace it with what they need. Therefore, the client side becomes more profitable in terms of performance and speed of miscalculations. I can’t say anything about code optimization (I don’t have time, sorry) :grinning:

1 Like

sorry for late reply but wouldn’t it be easy for cheaters to just not lower their stamina if I do it on the client? there are a couple code improvements that I did which I think increase preformance but are you sure it’s safe to control stamina on client side?

It’s not safe, there’s just no other more profitable way out. If the player’s properties are controlled by the player himself, then you should not bother correcting these jambs. Unless, of course, in your game such situations do not spoil the gameplay for others (in any case, this is true, but to some extent)