Issue with player releasing before all code runs

So I’m making an attack that’s chargeable for my fighting game. How it works is; player holds down key, initial animation starts and then starts doing the charging one, once the key is released, it’ll do a check to stop the looped charging anim and play the releasing one.

The problem is, if a player lets go of the key before the charging animation starts, it’ll do the checks to stop any animations but then, because the first code is still running, it’ll later begin the charging animation after everything is done and it leaves the player stuck like that since it’s looped.

This is all the move code

function skill.Local(data, Player, keyPressed, duration)
	if data then
		local character = Player.Character
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if not humanoid then
			warn("Humanoid not found.")
			return
		end

		local animator = humanoid:FindFirstChildOfClass("Animator")
		if not animator then
			animator = Instance.new("Animator")
			animator.Parent = humanoid
		end

		if keyPressed then
			for animName, animId in pairs(data.Animations) do
				if animName == "initial" then
					local animation = Instance.new("Animation")
					animation.AnimationId = animId
					animationTrack = animator:LoadAnimation(animation)
					animationTrack:Play()
						
				elseif animName == "hold" then
					task.wait(0.25)
					local animation = Instance.new("Animation")
					animation.AnimationId = animId
					animationTrack = animator:LoadAnimation(animation)
					animationTrack:Play()
				
					local startTime = tick()
					chargeConnection = RunService.RenderStepped:Connect(function()
						local elapsed = tick() - startTime
						local scale = 10 + (elapsed * 5)
						if scale > 30 then
							scale = 30
						end
						
					end)

					break
				end
			end
		else
			
			print(animationTrack)
			if animationTrack then
				animationTrack:Stop()
			end

			if chargeConnection then
				chargeConnection:Disconnect()
				chargeConnection = nil
			end
			
	



			for animName, animId in pairs(data.Animations) do
				if animName == "release" then
					local animation = Instance.new("Animation")
					animation.AnimationId = animId
					local anim2Track = animator:LoadAnimation(animation)
					anim2Track:Play()

					SkillExecutionEvent:FireServer(data, duration, script.Name)
					break
				end
			end
		end
	else
		warn("No data passed to skill.Local.")
	end
end

And here’s some framework stuff that could help ig:

local function onKeyPress(input, gameProcessed)
	if gameProcessed then return end
	local currentSkill = getSkillByKeybind(input.KeyCode)
	if toolEquipped and currentSkill and not isSkillOnCooldown(currentSkill) and (Player:GetAttribute("UsingSkill") == false) then
		keyPressStartTime = tick()
		local skillModule = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("SkillModule"):WaitForChild("Skills"):WaitForChild(currentSkill.SkillName))
		if skillModule.Local then
			skillModule.Local(currentSkill, Player, true)
		end
	end
end

local function onKeyRelease(input, gameProcessed)
	if gameProcessed then return end
	local currentSkill = getSkillByKeybind(input.KeyCode)
	if toolEquipped and currentSkill and not isSkillOnCooldown(currentSkill) and (Player:GetAttribute("UsingSkill") == false) then
		local keyPressDuration = tick() - keyPressStartTime
	
		Player:SetAttribute("UsingSkill",true)
		local skillModule = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("SkillModule"):WaitForChild("Skills"):WaitForChild(currentSkill.SkillName))
		if skillModule.Local then
			skillModule.Local(currentSkill, Player, false, keyPressDuration)
		end

		lastUsedTimes[currentSkill.SkillName] = tick()
		Player:SetAttribute("UsingSkill",false)
	end
end

UserInputService.InputBegan:Connect(onKeyPress)
UserInputService.InputEnded:Connect(onKeyRelease)

It seems like such a simple issue but I’m struggling to resolve in a well way, I want to make the script wait for like a second before doing the release code but because of how the code will automatically run if the key is released, it makes that hard to do with all the situations to account for like holding it for 0 or maybe 5 seconds. Any help is really appreciated, thanks!

1 Like

Ended up using a boolean to fix this, it’s set to true once all the charging stuff is done and then the second part has to wait for it to be true but’ll cancel within 5 seconds if it takes too long.

if keyPressed then
			finishedFirst = false
			for animName, animId in pairs(data.Animations) do
				if animName == "initial" then
					local animation = Instance.new("Animation")
					animation.AnimationId = animId
					animationTrack = animator:LoadAnimation(animation)
					animationTrack:Play()
				end
				end
				
				task.wait(0.25)
				for animName, animId in pairs(data.Animations) do
				if animName == "hold" then
					local animation = Instance.new("Animation")
					animation.AnimationId = animId
					animationTrack = animator:LoadAnimation(animation)
					animationTrack:Play()
					
					finishedFirst = true
					print(finishedFirst)
				
					
					
					end
			end
			
		else
		local now = tick()
		print(finishedFirst)
		while finishedFirst == false do
			task.wait(0.05)
			if tick() - now >= 5 then
				break
			end
		end

This is the solution I found, lemme know if you think there’s better ways to do this though

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.