Hey, i’m scripting a localscript fully dedicated to managing running in my game. What i do for now is connecting a function to UserInputService.InputBegan and UserInputService.InputEnded. What it does is toggling the run on and off.
Each character the player can use has a custom walking and running speed set in a module. What the toggle running function does is just changing the walkspeed of the player to either of those values.
Now i’ve ran into a problem. Throughout my match i want to be able to say, freeze the player. Or change the player’s walkspeed through a status effects (active like a Haste effect, or passive like being hit)
So if i freeze the player through the server, and the player just, runs, it will restart. Or if they are running and then frozen, or slowed down after stopping to run the walkspeed is reset to the normal walking speed and the freeze doesnt take effect.
How can i solve this? I already store plenty of value instances within the player. Should i make yet another one storing if the player’s running? I was thinking of using a heartbeat function instead too so i can add or remove multipliers from the player, is that a good idea or would that eat up cpu power?
If you’ve made something like this before and have an idea of how to do that i’d be thankful!
I’m sorry but I don’t quite get what you are trying to achieve here. Can you please be a bit more specific? Do you have a suitable example to illustrate your goal here?
Put shortly, im switching the walkspeed of the player between two values with a function connected to the inputBegan and inputEnded events. However when i just, set the walkspeed to some other value like 0, if i want to freeze the player: running or stopping to will reset the speed back.
What would be the best way to set up a running script, with the ability without overcomplicating things?
I apologize if i wasnt really clear with my question
I mean a local script, instead of a module script would complicate this. But you could have it so anything wanting to change the speed of the player grabs a ticket and returns it when they no longer want to adjust the users speed. Then you can have ticket priorities and basically just always apply the highest priority ticket that is still in the system and no tickets means default walking speed. That way you can send like a freeze ticket with a priority 99 or something to force it to override every other possible effect.
So think like this
local DEFUALT_SPEED = 16
local humanoid = game.Players.LocalPlayer.Character:WaitForChild("Humanoid") --Not strictly safe, but good enough for the example
local tickets = {}
local function updateSpeed()
local highestPriority = 0 --We assume all priorities are above 0 here btw
local highestName = ""
for name, info in pairs(tickets) do
if info[1] > highestPriority then
highestPriority = info[1]
highestName = name
elseif info[1] == highestPriority then
if tickets[name][3] > tickets[highestName][3] then --Same priority, later submission overrides.
highestName = name
end
end
end
if highestPriority == 0 then
humanoid.WalkSpeed = DEFAULT_SPEED
else
humanoid.WalkSpeed = tickets[highestName][2] --[2] is the speed. I could make them named or something for ease, but whatever.
end
end
local SpeedModule = {}
function SpeedModule.SetSpeed(name, priority, speed)
if tickets[name] then warn("Already have a ticket under the name: ", name) end
if priority < 1 then error("Priority has to be 1 or higher for the speed system") end
tickets[name] = {priority, speed, tick()}
updateSpeed()
end
function SpeedModule.UnsetSpeed(name)
if not tickets[name] then return warn("No ticket of name: ", name) end
tickets[name] = nil
updateSpeed()
end
return SpeedModule
It could potentially be cleaner if I just return a generated table when you make a ticket as a reference so that you can directly refer to it and just don’t have naming collisions at all. Probably better because it also helps enforce encapsulation since you can’t unbind a ticket from an unrelated script. But this does work. I would probably keep the names though for debugging. This strategy though could potentially go bad if you lose a reference to the table that you got when you made a ticket since you need it to return the ticket to prevent memory leaks and dead tickets being consumed, but that would be a usercode error, not an error here. The pure name version can potentially recover though since triggering the exit condition will always point to the correct name.