You can write your topic however you want, but you need to answer these questions:
I’m currently working on an anime combat game
What is the issue? Include screenshots / videos if possible!
My issue is that there are multiple scripts, and sources affecting the humanoid WalkSpeed, which causes the restoration and or setting of the walkspeed overwrite each other. For example, I have two attacks, After being hit by attack #1 I’d be stunned for 4 seconds, after the 4 seconds I set my walkspeed to 16. After being hit by attack #2 I’d be stunned for 2 seconds and returned to the base speed after those 2 seconds. The problem arises when I’m hit by attack #1, and then hit by attack number #2. Instead of waiting 4 seconds, attack #2 will overwrite attack #1 and return to the base speed before the first attacks 4 seconds. There are also other things like sprinting, blocking, and crouching. I want to manage all this with a module but I don’t know how to go about it.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I’ve been searching through the forum for a few days now, I keep finding shortcut-like solutions that wouldn’t work long-term or just very specific solutions that don’t apply to me. I did find two modules but they weren’t explained well.
Example:
local duration1 = 4
local duration2 = 2
local BaseSpeed = 16
local function attack1()
humanoid.WalkSpeed = 4
wait(duration1)
humanoid.WalkSpeed = BaseSpeed
end
local function attack2()
humanoid.WalkSpeed = 4
wait(duration2)
humanoid.WalkSpeed = BaseSpeed
end
attack1()
wait(1)
attack2()
--Attack 2 will return the walkspeed to BaseSpeed before the 4 second duration from Attack 1
I’d like someone to explain how I can implement this into my game. I might have worded this weirdly so If you have any questions let me know.
This could work but the thing is that there are other factors in the game that affect walkspeed like sprinting, blocking, etc. I forgot to mention that so I’ll edit the post, I think the ideal method of handling walkspeed would be to make a module script that I can use for all sources of walkspeed changes, I just need help figuring out how I’d go about doing that.
Ohh yea but I’m sure u can check if they are sprinting or blocking while ur doing the attack function but maybe use a module like i said im not very good at scriptinf
What I usually do is connect a PreRender (aka RenderStepped) event from RunService and do every check on the client. I know it’s not the safest method, but things like walkspeed and character movement should be handled on the client because of responsiveness, especially for combat games that involve a lot of movement.
Bit outdated but could give you a general idea on how to make it work
I think this will suffice for now, I know there is a more efficient way to do it but until I grow in terms of scripting knowledge this should be good. This is what I did.
This local script fires events to pass on True or False values depending on if the player is walking
uis.InputBegan:Connect(function(input,gpe)
if input.KeyCode == Enum.KeyCode.LeftShift then
mE:FireServer('Sprint', true)
if not character:FindFirstChild('Stunned') and humanoid.MoveDirection.Magnitude > 0 and player.canRun.Value == true then
runAnimTrack:Play()
end
end
if input.KeyCode == Enum.KeyCode.LeftControl then
mE:FireServer('Crouch', true)
end
end)
uis.InputEnded:Connect(function(input,gpe)
if input.KeyCode == Enum.KeyCode.LeftShift then
mE:FireServer('Sprint', false)
runAnimTrack:Stop()
end
if input.KeyCode == Enum.KeyCode.LeftControl then
mE:FireServer('Crouch', false)
end
end)
I used RenderStepped as suggested to check the attributes that are set by the server.
runService.RenderStepped:Connect(function()
if character:GetAttribute('Running') == true then
--print('Running')
humanoid.WalkSpeed = character.Attributes.SprintSpeed.Value
elseif character:GetAttribute('Walking') == true then
-- print('Walking')
humanoid.WalkSpeed = character.Attributes.BaseSpeed.Value
elseif character:GetAttribute('Punching') == true and character:GetAttribute('Stunned') == false and character:GetAttribute('Running') == false then
humanoid.WalkSpeed = character.Attributes.BaseSpeed.Value/2
-- print('Punching')
elseif character:GetAttribute('Stunned') then
humanoid.WalkSpeed = 0
elseif player.isBlocking.Value then
humanoid.WalkSpeed = baseSpeed/2.5
end
end)
The issue with overlapping should be solved with the checking using renderstepped. Thank you for the suggestion! I was thinking of using this but I didn’t think it would work as intended. If there are any practices I could utilize or improve upon in my code, please also let me know. Im also not sure if I should just handle this on the server since it requires events anyway.
The only other suggestion I can give you is to make sure you setup every walkspeed with the correct priority. So if stun walkspeed should be prioritized over running (which i’m guessing would be the case), make sure to put the stun if before the running if.
local walkspeed = character.Attributes.BaseSpeed.Value; -- we use a variable that is set to the base speed the character would have if none of the checks we do are true
if character:GetAttribute("Stunned") == true then -- since stunning completely stops the character, it should be prioritized so we don't perform needless checks later
walkspeed = 0;
elseif player.IsBlocking.Value then -- blocking seems to be the next slowest walkspeed, so we put it just under stunning
walkspeed = baseSpeed / 2.5;
elseif character:GetAttribute("Punching") == true then -- same logic for punching
walkspeed /= 2;
elseif character:GetAttribute("Running") == true then
walkspeed = character.Attributes.SprintSpeed.Value;
end;
humanoid.WalkSpeed = walkspeed;
This is how i’d do it personally but it changes on a case by case basis.
Why not? It’s clean and reliable. If he used events he’d have to connect so many of them (running/blocking/punching/etc) for every attribute/value that he needs to check and then check for the same parameters everytime. The code would get too long, while with RenderStepped you ensure the player has the correct speed every frame.
Using events would take too long/be too messy and module scripts are probably what I will use later on if I need to but using runservice also kills two birds with one stone, the player walkspeed is now protected by this since the players speed is virtually what it needs to be at all times.