Holding Key and pressing key

Concept:

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local HoldingTime = 0
local IsHolding = false

UserInputService.InputBegan:Connect(function(Input, IsChatting)
	if not IsChatting and Input.KeyCode == Enum.KeyCode.E then
		IsHolding = true
		print("Holding")
	end
end)

UserInputService.InputEnded:Connect(function(Input)
	-- We dont need to detect the IsChatting method for this one
	-- If im not wrong holding E and then pressing / and releasing E,
	-- This function will not fire.

	if Input.KeyCode == Enum.KeyCode.E then
		IsHolding = false
		print(HoldingTime)
		HoldingTime = 0
	end
end)

RunService.Heartbeat:Connect(function(TimeElapsed)
	if IsHolding then
		HoldingTime += TimeElapsed
	end
end)

Maybe it’s not the best way, I find it reliable

Screen Shot 2021-11-24 at 6.39.52 PM

You can adjust the scripts and mix them together to make it compatible. oK bye

1 Like

you can connect a function at

UserInputService.InputBegan

and then detect the button stopping being pressed at

UserInputService.InputEnded
1 Like

i am doing that but if I hold e and even if I let go of it, it will do the animation and then go back to the start and then do it again

This happens https://gyazo.com/cf241628fec74d3cc49ac66bf0477869
I let go of it, it does the punch but go back to holding and do the punch again.

local uis = game:GetService("UserInputService")
local tool = script.Parent
local rs = game:GetService("ReplicatedStorage")
local modules = rs.Modules
local fruitmodules = modules.Fruit
local module = require(fruitmodules["Devil Fruits"])
local Player = game.Players.LocalPlayer
local ts = game:GetService("TweenService")
local tweeninfo = TweenInfo.new(10, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)

local function xmove(plr)
	print(tostring(plr))
end

local function zmove()
		script.Parent.SFX["Ice Spikes"].Summon:Play()
		module.Hie.Spike(Player, 3)
		wait(3)
		script.Parent.SFX["Ice Spikes"].Disappear:Play()
		print("z move is active")
end

local cooldown = false
local HoldingTime = 0
local IsHolding = false

uis.InputBegan:Connect(function(Input, isHold)
	if not isHold and Input.KeyCode == Enum.KeyCode.E then
		if cooldown == false then
			local track = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.HoldIceSpikes)
			track:Play()
			IsHolding = true
			wait(5)
			cooldown = true
			local track1 = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.PunchIceSpikes)
			track1:Play()
			track:Stop()
			track1:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
				zmove()
				wait(3)
				cooldown = false
			end)
			print("Holding")
		end
	end
end)

uis.InputEnded:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.E then
		if cooldown == false then
			cooldown = true
			IsHolding = false
			print(HoldingTime)
			local track = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.PunchIceSpikes)
			track:Play()
			track:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
				zmove()
				wait(3)
				cooldown = false
			end)
			HoldingTime = 0
		end
	end
end)

No, did you scroll down my script? That’s not what I did

the isHold is actually to tell if the game has processed the keycode or not (if it’s used for chatting etc.)

and what you’re doing right now is registering whenever the keycode is E.
Instead, if you want to register how long the player held the key and if the person is still holding it, you should do something like

local holdingTime = 0
local boolEndHold = false

uis.InputChanged:Connect(function(inputObject, gameProcessedBool)
    if not gameProcessedBool and inputObject.KeyCode == Enum.KeyCode.E then
		if inputObject.UserInputState == Enum.UserInputState.Begin then
			task.spawn(function()
				while not boolEndHold do
					wait(1)
					holdingTime += 1
				end
			end)
			
			-- your code for when player starts holding key
		elseif inputObject.UserInputState == Enum.UserInputState.End then
			boolEndHold = false
			print("Held key for "..tostring(holdingTime).." seconds!")
			
			-- your code for when player stopped holding key
		end
    end
end)

You might also want to halt any other playing animations on the animator/humanoid before playing a new one

1 Like

I copied the heartbeat part, it still did the same thing sadly

local uis = game:GetService("UserInputService")
local tool = script.Parent
local rs = game:GetService("ReplicatedStorage")
local modules = rs.Modules
local fruitmodules = modules.Fruit
local module = require(fruitmodules["Devil Fruits"])
local Player = game.Players.LocalPlayer
local ts = game:GetService("TweenService")
local tweeninfo = TweenInfo.new(10, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local RunService = game:GetService("RunService")

local function xmove(plr)
	print(tostring(plr))
end

local function zmove()
		script.Parent.SFX["Ice Spikes"].Summon:Play()
		module.Hie.Spike(Player, 3)
		wait(3)
		script.Parent.SFX["Ice Spikes"].Disappear:Play()
		print("z move is active")
end

local cooldown = false
local HoldingTime = 0
local IsHolding = false

uis.InputChanged:Connect(function(inputObject, gameProcessedBool)
	if not gameProcessedBool and inputObject.KeyCode == Enum.KeyCode.E then
		if inputObject.UserInputState == Enum.UserInputState.Begin then
			task.spawn(function()
				while not IsHolding do
					wait(1)
					HoldingTime += 1
				end
			end)
			local track = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.HoldIceSpikes)
			track:Play()
			wait(5)
			cooldown = true
			local track1 = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.PunchIceSpikes)
			track1:Play()
			track:Stop()
			track1:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
				zmove()
				wait(3)
				cooldown = false
			end)
			print("Holding")
		elseif inputObject.UserInputState == Enum.UserInputState.End then
			IsHolding = false
			print("Held key for "..tostring(HoldingTime).." seconds!")
			if cooldown == false then
				cooldown = true
				local track = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.PunchIceSpikes)
				track:Play()
				track:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
					zmove()
					wait(3)
					cooldown = false
				end)
			end
		end
	end
end)

like this?

1 Like

Yes and
Hmm, for the future, you should mount animations on the

Humanoid:WaitForChild("Animator")

instead of humanoid.
But now that you’re using humanoid, try stopping the playing tracks first before playing a new one:

for _, animationTrack in pairs(Humanoid:GetPlayingAnimationTracks()) do
    animationTrack:Stop()
end
uis.InputChanged:Connect(function(inputObject, gameProcessedBool)
	if not gameProcessedBool and inputObject.KeyCode == Enum.KeyCode.E then
		if inputObject.UserInputState == Enum.UserInputState.Begin then
			task.spawn(function()
				while not IsHolding do
					wait(1)
					HoldingTime += 1
				end
			end)
			local track = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.HoldIceSpikes)
			for _, animationTrack in pairs(Player.Character.Humanoid:GetPlayingAnimationTracks()) do
				animationTrack:Stop()
			end
			track:Play()
			wait(5)
			cooldown = true
			local track1 = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.PunchIceSpikes)
			for _, animationTrack in pairs(Player.Character.Humanoid:GetPlayingAnimationTracks()) do
				animationTrack:Stop()
			end
			track1:Play()
			track:Stop()
			track1:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
				zmove()
				wait(3)
				cooldown = false
			end)
			print("Holding")
		elseif inputObject.UserInputState == Enum.UserInputState.End then
			IsHolding = false
			print("Held key for "..tostring(HoldingTime).." seconds!")
			if cooldown == false then
				cooldown = true
				local track = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.PunchIceSpikes)
				for _, animationTrack in pairs(Player.Character.Humanoid:GetPlayingAnimationTracks()) do
					animationTrack:Stop()
				end
				track:Play()
				track:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
					zmove()
					wait(3)
					cooldown = false
				end)
			end
		end
	end
end)

hows this?

I think that would work, though optimizing is another story

It does nothing when I hold e or press it

Move the for loop stopping animationtracks above the line where you’re loading the animation track, so

for loop
local track1 = ...

Also if that doesn’t work, I’m not sure but you should just return to your older code and try if the other answers are useful.

local uis = game:GetService("UserInputService")
local tool = script.Parent
local rs = game:GetService("ReplicatedStorage")
local modules = rs.Modules
local fruitmodules = modules.Fruit
local module = require(fruitmodules["Devil Fruits"])
local Player = game.Players.LocalPlayer
local ts = game:GetService("TweenService")
local tweeninfo = TweenInfo.new(10, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local RunService = game:GetService("RunService")

local function xmove(plr)
	print(tostring(plr))
end

local function zmove()
		script.Parent.SFX["Ice Spikes"].Summon:Play()
		module.Hie.Spike(Player, 3)
		wait(3)
		script.Parent.SFX["Ice Spikes"].Disappear:Play()
		print("z move is active")
end

local cooldown = false
local HoldingTime = 0
local IsHolding = false

uis.InputChanged:Connect(function(inputObject, gameProcessedBool)
	if script.Parent.Equip.Value == true then
		if not gameProcessedBool and inputObject.KeyCode == Enum.KeyCode.E then
			if inputObject.UserInputState == Enum.UserInputState.Begin then
				task.spawn(function()
					while not IsHolding do
						wait(1)
						HoldingTime += 1
					end
				end)
				if cooldown == false then
					for _, animationTrack in pairs(Player.Character.Humanoid:GetPlayingAnimationTracks()) do
						animationTrack:Stop()
					end
					local track = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.HoldIceSpikes)
					track:Play()
					wait(5)
					cooldown = true
					for _, animationTrack in pairs(Player.Character.Humanoid:GetPlayingAnimationTracks()) do
						animationTrack:Stop()
					end
					local track1 = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.PunchIceSpikes)
					track1:Play()
					track:Stop()
					track1:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
						zmove()
						wait(3)
						cooldown = false
					end)
					print("Holding")
				end
			elseif inputObject.UserInputState == Enum.UserInputState.End then
				IsHolding = false
				print("Held key for "..tostring(HoldingTime).." seconds!")
				if cooldown == false then
					cooldown = true
					for _, animationTrack in pairs(Player.Character.Humanoid:GetPlayingAnimationTracks()) do
						animationTrack:Stop()
					end
					local track = Player.Character.Humanoid:LoadAnimation(script.Parent.Animations.PunchIceSpikes)
					track:Play()
					track:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
						zmove()
						wait(3)
						cooldown = false
					end)
				end
			end
		end
	end
end)

I did everything u said, it still doesn’t do anything at all, not even print, do I perhaps have to include the inputbegan?

local UIS = game:GetService("UserInputService")
local RS = game:GetService("ReplicatedStorage")
local Modules = RS:WaitForChild("Modules")
local Fruit = Modules:WaitForChild("Fruit")
local FM = Fruit:WaitForChild("Devil Fruits")
local FruitModule = require(FM)
local Tool = script.Parent
local ISSummon = Tool:WaitForChild("SFX"):WaitForChild("Ice Spikes"):WaitForChild("Summon")
local ISDisappear = Tool:WaitForChild("SFX"):WaitForChild("Ice Spikes"):WaitForChild("Disappear")
local Anims = Tool:WaitForChild("Animations")
local HIS = Anims:WaitForChild("HoldIceSpikes")
local PIS = Anims:WaitForChild("PunchIceSpikes")
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local HISAnim = Humanoid:LoadAnimation(HIS)
local PISAnim = Humanoid:LoadAnimation(PIS)
local Cooldown = false
local Holding = false

local function zmove()
	ISSummon:Play()
	FruitModule.Hie.Spike(Player, 3)
	task.wait(3)
	ISDisappear:Play()
end

UIS.InputBegan:Connect(function(Input, Processed)
	if Processed then
		return
	end
	if Tool.Equip.Value then
		local Gui = PlayerGui[Tool.Name .. " Moveset"]
		if Input.KeyCode == Enum.KeyCode.E then
			if not Cooldown then
				if not Holding then
					Cooldown = true
					Holding = true
					HISAnim:Play()
					Humanoid.WalkSpeed = 0
					task.wait(5)
					HISAnim:Stop()
					PISAnim:Play()
					PISAnim:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
						zmove()
						task.wait(3)
						Cooldown = false
					end)
					Humanoid.WalkSpeed = 18
					Holding = false
				end
			end
		end
	end
end)

UIS.InputEnded:Connect(function(Input, Processed)
	if Processed then
		return
	end
	if Tool.Equip.Value then
		if Input.KeyCode == Enum.KeyCode.E then
			if not Cooldown then
				if not Holding then
					Cooldown = true
					Holding = true
					HISAnim:Stop()
					PISAnim:Play()
					PISAnim:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
						Humanoid.WalkSpeed = 0
						zmove()
						task.wait(3)
						Cooldown = false
					end)
					Humanoid.WalkSpeed = 18
					Holding = false
				end
			end
		end
	end
end)

Captain cleanup to the rescue. Load animations outside of event callbacks/loops to prevent reloading the same AnimationTrack instances repetitively. They only need to be loaded once, then they can be played as many times as you desire, I’ve also fixed up a few other things like stopping the HoldIceSpikes animation when the input ends.

it doesnt let me end the input and just forces me to do the hold animation then wait then punch animation, I cant end it midway and do the punch animation

local UIS = game:GetService("UserInputService")
local RS = game:GetService("ReplicatedStorage")
local Modules = RS:WaitForChild("Modules")
local Fruit = Modules:WaitForChild("Fruit")
local FM = Fruit:WaitForChild("Devil Fruits")
local FruitModule = require(FM)
local Tool = script.Parent
local ISSummon = Tool:WaitForChild("SFX"):WaitForChild("Ice Spikes"):WaitForChild("Summon")
local ISDisappear = Tool:WaitForChild("SFX"):WaitForChild("Ice Spikes"):WaitForChild("Disappear")
local Anims = Tool:WaitForChild("Animations")
local HIS = Anims:WaitForChild("HoldIceSpikes")
local PIS = Anims:WaitForChild("PunchIceSpikes")
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local HISAnim = Humanoid:LoadAnimation(HIS)
local PISAnim = Humanoid:LoadAnimation(PIS)
local Cooldown1 = false
local Holding1 = false
local Cooldown2 = false
local Holding2 = false

local function zmove()
	ISSummon:Play()
	FruitModule.Hie.Spike(Player, 3)
	task.wait(3)
	ISDisappear:Play()
end

UIS.InputBegan:Connect(function(Input, Processed)
	if Processed then
		return
	end
	if Tool.Equip.Value then
		local Gui = PlayerGui[Tool.Name .. " Moveset"]
		if Input.KeyCode == Enum.KeyCode.E then
			if not Cooldown1 then
				if not Holding1 then
					Cooldown1 = true
					Holding1 = true
					HISAnim:Play()
					Humanoid.WalkSpeed = 0
					HISAnim:Stop()
					PISAnim:Play()
					PISAnim:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
						zmove()
						task.wait(3)
						Cooldown1 = false
					end)
					task.wait(5)
					Humanoid.WalkSpeed = 18
					Holding1 = false
				end
			end
		end
	end
end)

UIS.InputEnded:Connect(function(Input, Processed)
	if Processed then
		return
	end
	if Tool.Equip.Value then
		if Input.KeyCode == Enum.KeyCode.E then
			if not Cooldown2 then
				if not Holding2 then
					Cooldown2 = true
					Holding2 = true
					HISAnim:Stop()
					PISAnim:Play()
					PISAnim:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
						Humanoid.WalkSpeed = 0
						zmove()
						task.wait(3)
						Cooldown2 = false
					end)
					Humanoid.WalkSpeed = 18
					Holding2 = false
				end
			end
		end
	end
end)

I’ve moved the yielding function (wait) until after the animations are played and created 2 additional variables for the InputEnded event.

I want the ice spikes animation to activate when the player is holding the key for 5 seconds, I gtg, just post ur reply ill read it tmr and see if it solves it

local UIS = game:GetService("UserInputService")
local RS = game:GetService("ReplicatedStorage")
local Modules = RS:WaitForChild("Modules")
local Fruit = Modules:WaitForChild("Fruit")
local FM = Fruit:WaitForChild("Devil Fruits")
local FruitModule = require(FM)
local Tool = script.Parent
local ISSummon = Tool:WaitForChild("SFX"):WaitForChild("Ice Spikes"):WaitForChild("Summon")
local ISDisappear = Tool:WaitForChild("SFX"):WaitForChild("Ice Spikes"):WaitForChild("Disappear")
local Anims = Tool:WaitForChild("Animations")
local HIS = Anims:WaitForChild("HoldIceSpikes")
local PIS = Anims:WaitForChild("PunchIceSpikes")
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local HISAnim = Humanoid:LoadAnimation(HIS)
local PISAnim = Humanoid:LoadAnimation(PIS)
local Cooldown1 = false
local Holding1 = false
local Cooldown2 = false
local Holding2 = false

local function zmove()
	ISSummon:Play()
	FruitModule.Hie.Spike(Player, 3)
	task.wait(3)
	ISDisappear:Play()
end

UIS.InputBegan:Connect(function(Input, Processed)
	if Processed then
		return
	end
	if Tool.Equip.Value then
		local Gui = PlayerGui[Tool.Name .. " Moveset"]
		if Input.KeyCode == Enum.KeyCode.E then
			if not Cooldown1 then
				if not Holding1 then
					Cooldown1 = true
					Holding1 = true
					HISAnim:Play()
					Humanoid.WalkSpeed = 0
					local startTime = tick()
					repeat task.wait()
						local currTime = tick() - startTime
						local keysPressed = UIS:GetKeysPressed()
						if not table.find(keysPressed, Enum.KeyCode.E) then
							return
						end
					until currTime >= 5
					HISAnim:Stop()
					PISAnim:Play()
					PISAnim:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
						zmove()
						task.wait(3)
						Cooldown1 = false
					end)
					Humanoid.WalkSpeed = 18
					Holding1 = false
				end
			end
		end
	end
end)

UIS.InputEnded:Connect(function(Input, Processed)
	if Processed then
		return
	end
	if Tool.Equip.Value then
		if Input.KeyCode == Enum.KeyCode.E then
			if not Cooldown2 then
				if not Holding2 then
					Cooldown2 = true
					Holding2 = true
					HISAnim:Stop()
					PISAnim:Play()
					PISAnim:GetMarkerReachedSignal("Ice Spikes"):Connect(function()
						Humanoid.WalkSpeed = 0
						zmove()
						task.wait(3)
						Cooldown2 = false
					end)
					Humanoid.WalkSpeed = 18
					Holding2 = false
				end
			end
		end
	end
end)

Didn’t realise that was the behavior you were trying to achieve, here you go (you may need to remove/modify the cooldowns slightly.

1 Like

I will try that later, thank you.