Back Story
I'm trying to make a melee scripts with 4 combos. Left punch, Right Punch, Right Kick and Head Butt. Animations,Damage and all that work. This is a pretty advanced combo system with damage indicators and particles basically things you would see in something that has a lot to do with hand on hand combat. What I'm trying to do is make it so that when the player punches the players walkspeed is set to something low like 2 and then once the punch is over its set to the speed the just once was.
Problem
My problem is the waits()
. When you wait()
it stops your whole code completely waiting r and then proceeding the code. I need waits so that i tell the game to wait this so amount of seconds until turning the players walkspeed back to normal. So with the wait()
what basically happens is that when I click and start the melee combos there is always a slight. delay because of that wait. Which doesn't make the combo feel great and if I do remove the waits there is always a small little space where the players walkspeed goes to normal and then to that low value.
game.ReplicatedStorage.StaminaRem.ARemote.OnServerEvent:Connect(function(Player) local tweenInfo1 = TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out,0,false) if en == false then return end if char.Stun.Value == false then en = false local Wave = game.ReplicatedStorage if tick()-timer > 0.7 then on = 1 end newhitbox() local root = char:FindFirstChild("HumanoidRootPart") local bp2 = Instance.new("BodyVelocity",char.Torso) game:GetService("Debris"):AddItem(bp2,0.1) bp2.MaxForce = Vector3.new(math.huge,math.huge,math.huge) bp2.Velocity = root.CFrame.LookVector*10 if char.Humanoid.WalkSpeed ~= 16 then running = true else running = false end script.Parent.Miss:Play() timer = tick() local char = Tool.Parent local hum = char:WaitForChild("Humanoid") local anim = hum:LoadAnimation(script.Parent["Animation"..on]) anim:Play() swinging = true char.Humanoid.WalkSpeed = 2 wait(0.4) if running == true then wait(0.2) char.Humanoid.WalkSpeed = Player.Stats.Agility.Value * 0.4 + 16 else wait(0.2) char.Humanoid.WalkSpeed = 16 end on = on + 1 if on >= 5 then on = 1 wait(0.6) end en = true swinging = false end end)
You can use spawn() to do the wait in a separate thread while you do other things.
spawn(function() if running == true then wait(0.2) char.Humanoid.WalkSpeed = Player.Stats.Agility.Value * 0.4 + 16 else wait(0.2) char.Humanoid.WalkSpeed = 16 end end)
This code will be executed in parallel to the rest of your code. So execution will continue while this code is running and there will be no delay.
You have a couple of options.
Option 1 is to use events from the AnimationTrack to reset the player's move speed precisely when the animation ends or reaches a specific track marker. You can use the AnimationTrack.Stopped or you can put markers in the animation and connect to AnimationTrack:GetMarkerReachedSignal("Your Marker Name"). This approach will generalize to different duration punches, and let you decide on the animation timeline when a specific reset event should fire.
Option 2 is to use a coroutine to wait some fixed amount of time. This is the same approach as the suggestion to use spawn(), but without adding spawn's extra 1 to 2 frames of delay (which you have no control over), so it can potentially time things a little more tightly.
While it requires a little extra setup, and probably republishing animations, using track markers (or track-ended events) is how this sort of thing is usually done in professionally-made games, and how I'd do it. I would not personally spawn new Lua threads with wait timers for every punch.