Touch Event NOT working after player dies/reset character

Hi! I’m new at scripting so I really don’t want to start a post without checking and searching for answers that have the same problem as me, but so far I haven’t found anything that works. So here I am:

  1. What do I want to achieve?
    – I just want to code to work after a player dies/reset

  2. What is the issue?
    – The code works perfectly when I run it the first time, but whenever the player dies the code just stops at the Touched event.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    – I was thinking about disconnecting the Touch Event when a player dies but I’m not sure how to go about it in my code.

robloxapp-20200607-1014222.wmv (3.6 MB)
–I was clicking and pressing keys after I reset but nothing is happening

image
–I also tried putting it in StarterPLayerScripts ->the script didn’t work entirely

HERE’S MY CODE:
FIRST TRY:

Summary
----------//Service\\-----------------
local Players = game:GetService("Players")
local ContextActionService = game:GetService("ContextActionService")
local fightModule = require(script.Parent:WaitForChild("FightScript"))
local UserInputService = game:GetService("UserInputService")

----------//Variables\\-----------------
local jab = script:WaitForChild("Jab")
local rightHook = script:WaitForChild("RightHook")
local upperCut = script:WaitForChild("UpperCut")
local block = script:WaitForChild("Block")
local enabled = false
local cooldown = 0.5
local damage

local FIGHT_ANIM = "Fighting Animation"

----------//Bind Function\\-----------------
local function fightAnim(actionName, inputState, inputObj)
	local humanoid = game.Players.LocalPlayer.Character:WaitForChild("Humanoid")
	
	if inputState == Enum.UserInputState.Begin and enabled == false and inputObj.UserInputType == Enum.UserInputType.MouseButton1 then 
		enabled = true
		local anim = humanoid:LoadAnimation(jab)
		anim:Play()
		fightModule.Fight(anim.Name)
		wait(cooldown)
		enabled = false
	end
				
	if inputObj.KeyCode == Enum.KeyCode.F and enabled == false then
		enabled = true
		local anim = humanoid:LoadAnimation(rightHook)
		anim:Play()
		fightModule.Fight(anim.Name)
		wait(cooldown)
		enabled = false
	end
	
	if inputObj.KeyCode == Enum.KeyCode.E and enabled == false then
		enabled = true
		local anim = humanoid:LoadAnimation(upperCut)
		anim:Play()
		fightModule.Fight(anim.Name)
		wait(cooldown)
		enabled = false
	end

	if inputObj.KeyCode == Enum.KeyCode.Space then
		local anim = humanoid:LoadAnimation(block)
		UserInputService.InputBegan:Connect(function()
			if not UserInputService:IsKeyDown(Enum.KeyCode.Space) then
				if anim.IsPlaying then
					anim:Stop()
					fightModule.Fight(anim.Name)
				end
			else
				anim:Play()
				fightModule.Fight(anim.Name)
			end
		end)
	end

end

----------//Touched Functions\\-----------------
local function onTouched( limb )
	return function ( hit )
		if hit.Name == "sparStage" then
			print(hit.Name)  -----Does not work up to here when player dies/resets
			ContextActionService:BindAction(FIGHT_ANIM, fightAnim, false, Enum.UserInputType.MouseButton1, Enum.KeyCode.F, Enum.KeyCode.E, Enum.KeyCode.Space)
		end
	end
end

local function onTouchEnded( limb )
	return function ( hit )
		if hit.Name == "sparStage" then
			ContextActionService:UnbindAction(FIGHT_ANIM)
		end
	end
end

----------//Checking Players\\-----------------
local function onCharacterAdded( chr )
	local hum = chr:FindFirstChild( "Humanoid" )
	if hum then
		local leftFoot = chr:FindFirstChild( "LeftFoot" )
		local rightFoot = chr:FindFirstChild( "RightFoot" )
		local upperTorso = chr:FindFirstChild( "UpperTorso" )
		
		leftFoot.Touched:Connect( onTouched( leftFoot ) )
		leftFoot.TouchEnded:Connect( onTouchEnded( leftFoot ) )
		rightFoot.Touched:Connect( onTouched( rightFoot ) )
		rightFoot.TouchEnded:Connect( onTouchEnded( rightFoot ) )
		upperTorso.Touched:Connect( onTouched( upperTorso ) )
		upperTorso.TouchEnded:Connect( onTouchEnded( upperTorso ) )
		print(chr.Name) ---Just used this to see if it works up to here
	end
end

local function onPlayerAdded(player)
	-- Check if they already spawned in
	if player.Character then
		onCharacterAdded(player.Character)
	end
	-- Listen for the player (re)spawning 
	player.CharacterAdded:Connect(onCharacterAdded)
end
 
-- Iterate over each player already connected
-- to the game using a generic for-loop
for i, player in pairs(Players:GetPlayers()) do
	onPlayerAdded(player)
end
-- Listen for newly connected players
Players.PlayerAdded:Connect(onPlayerAdded)

**UPDATED: I remove the player added codes but still got the problem
UPDATED CODE:

Summary
----------//Service\\-----------------
local ContextActionService = game:GetService("ContextActionService")
local fightModule = require(script.Parent:WaitForChild("FightScript"))
local UserInputService = game:GetService("UserInputService")

----------//Variables\\-----------------
local Player = game.Players.LocalPlayer 
local Character = Player.Character

local jab = script:WaitForChild("Jab")
local rightHook = script:WaitForChild("RightHook")
local upperCut = script:WaitForChild("UpperCut")
local block = script:WaitForChild("Block")
local enabled = false
local cooldown = 0.5
local damage

local FIGHT_ANIM = "Fighting Animation"

----------//Bind Function\\-----------------
local function fightAnim(actionName, inputState, inputObj)
	local humanoid = game.Players.LocalPlayer.Character:WaitForChild("Humanoid")
	
	if inputState == Enum.UserInputState.Begin and enabled == false and inputObj.UserInputType == Enum.UserInputType.MouseButton1 then 
		enabled = true
		local anim = humanoid:LoadAnimation(jab)
		anim:Play()
		fightModule.Fight(anim.Name)
		wait(cooldown)
		enabled = false
	end
				
	if inputObj.KeyCode == Enum.KeyCode.F and enabled == false then
		enabled = true
		local anim = humanoid:LoadAnimation(rightHook)
		anim:Play()
		fightModule.Fight(anim.Name)
		wait(cooldown)
		enabled = false
	end
	
	if inputObj.KeyCode == Enum.KeyCode.E and enabled == false then
		enabled = true
		local anim = humanoid:LoadAnimation(upperCut)
		anim:Play()
		fightModule.Fight(anim.Name)
		wait(cooldown)
		enabled = false
	end

	if inputObj.KeyCode == Enum.KeyCode.Space then
		local anim = humanoid:LoadAnimation(block)
		UserInputService.InputBegan:Connect(function()
			if not UserInputService:IsKeyDown(Enum.KeyCode.Space) then
				if anim.IsPlaying then
					anim:Stop()
					fightModule.Fight(anim.Name)
				end
			else
				anim:Play()
				fightModule.Fight(anim.Name)
			end
		end)
	end

end

----------//Touched Functions\\-----------------
local function onTouched( limb )
	print(limb.Name)
	return function ( hit )
		if hit.Name == "sparStage" then
			print(hit.Name)  -----Does not work up to here when player dies/resets
			ContextActionService:BindAction(FIGHT_ANIM, fightAnim, false, Enum.UserInputType.MouseButton1, Enum.KeyCode.F, Enum.KeyCode.E, Enum.KeyCode.Space)
		end
	end
end

local function onTouchEnded( limb )
	return function ( hit )
		if hit.Name == "sparStage" then
			ContextActionService:UnbindAction(FIGHT_ANIM)
		end
	end
end


----------//Checking Players\\-----------------
local function onCharacterAdded( chr )
	local hum = chr:WaitForChild( "Humanoid" )
	if hum then
		local leftFoot = chr:FindFirstChild( "LeftFoot" )
		local rightFoot = chr:FindFirstChild( "RightFoot" )
		local upperTorso = chr:FindFirstChild( "UpperTorso" )
		
		leftFoot.Touched:Connect( onTouched( leftFoot ) )
		leftFoot.TouchEnded:Connect( onTouchEnded( leftFoot ) )
		rightFoot.Touched:Connect( onTouched( rightFoot ) )
		rightFoot.TouchEnded:Connect( onTouchEnded( rightFoot ) )
		upperTorso.Touched:Connect( onTouched( upperTorso ) )
		upperTorso.TouchEnded:Connect( onTouchEnded( upperTorso ) )
		print(chr.Name)
	end
end

-- Check if they already spawned in
if Character then
	onCharacterAdded(Character)
end
-- Listen for the player (re)spawning 
Player.CharacterAdded:Connect(onCharacterAdded)

Any help is appreciated! Thank you so much in advance!

Is this a server script or a local script? If it’s a local script you’ll have to do this differently.

1 Like

It is a local script, the “FightAnimation” on the screenshot, How do you mean differently?

I see. .PlayerAdded can’t be used in a LocalScript. You can listen to the .Touched events directly without .PlayerAdded and .CharacterAdded, because it is in the StarterCharacterScripts, which means that the script would reset everytime the player dies.

1 Like

Oh really? So, should I just set a variable for Local Player to fire the touch events then?

Local scripts in starterCharacterScripts are actually copied into everone’s character whenever they spawn. It’s like everyone gets a copy of the script whenever their character is added. So instead of waiting for a player to join and attaching those functions to the player, you can just index the character in that script and attach the touched functions to it. Sorry if this is kind of confusing.

Here’s an example: (Local script in starter character scripts)

local Player = game.Players.LocalPlayer 
local Character = Player.Character

Character.LeftFoot.Touched:Connect(function()
    -- do stuff
end)

This would work because this script is copied into the player’s character whenever they spawn.

If you want to see for yourself you can put a local script in startercharacterscripts and then playtest, there should be a copy of that local script under your character.

1 Like

You don’t even need the player for this, do you? I’m sorry, I did not read the entire script.

Now that the script is inside the character, you can do:

script.Parent.LeftArm.Touched:Connect(function(touchPart)
    print("Touched, touched by "..touchPart.Name)
end)

Instead of waiting for the character to load in via the player.CharacterAdded().

1 Like

So, I Removed the player added codes, then added this

local Player = game.Players.LocalPlayer 
local Character = Player.Character

then did this

local function onCharacterAdded( chr )
	local hum = chr:FindFirstChild( "Humanoid" )
	if hum then
		local leftFoot = chr:FindFirstChild( "LeftFoot" )
		local rightFoot = chr:FindFirstChild( "RightFoot" )
		local upperTorso = chr:FindFirstChild( "UpperTorso" )
		
		leftFoot.Touched:Connect( onTouched( leftFoot ) )
		leftFoot.TouchEnded:Connect( onTouchEnded( leftFoot ) )
		rightFoot.Touched:Connect( onTouched( rightFoot ) )
		rightFoot.TouchEnded:Connect( onTouchEnded( rightFoot ) )
		upperTorso.Touched:Connect( onTouched( upperTorso ) )
		upperTorso.TouchEnded:Connect( onTouchEnded( upperTorso ) )
		print(chr.Name)
	end
end

onCharacterAdded(Character)

It worked up to printing the character name but not up to this part

local function onTouched( limb )
	return function ( hit )
		if hit.Name == "sparStage" then
			print(hit.Name)  -----Does not work up to here when player dies/resets
			ContextActionService:BindAction(FIGHT_ANIM, fightAnim, false, Enum.UserInputType.MouseButton1, Enum.KeyCode.F, Enum.KeyCode.E, Enum.KeyCode.Space)
		end
	end
end

So-- I still have the problem. :pensive:

Is that your whole script? It looks like you never called onCharacterAdded anywhere in your script so it would never run.

Edit: nvm, didn’t read it right

if hit.Name == "sparStage" then

Maybe it’s just that hit’s name wasn’t sparStage? Try printing something before that line too.

So, like in @C0lvy123 suggestion, I tried to set “Player = script.Parent” and used it for firing the touch event, and it also works the first time but not after the player dies

it is, since it works the first time I run it, but not when the player dies/reset

This is not true. PlayerAdded can be used on the client and will fire as expected.

Your issue boils down to a few key points:

  1. As others have stated, use the local player Players.LocalPlayer instead of connecting to all other players.

  2. Put your script into StarterPlayerScripts along with your module to prevent it reloading with every new character.

  3. Replace local hum = chr:FindFirstChild( "Humanoid" ) with :WaitForChild instead. This returns nil when the character first loads because the humanoid isn’t added yet.

I made these three changes with your code in an empty baseplate and it worked like a charm with every reset.

Edit: Here's the code I used for the last part of your script, the Checking Players section...
----------//Checking Player\\-----------------
local function onCharacterAdded( chr )
	local hum = chr:WaitForChild( "Humanoid" )
	if hum then
		local leftFoot = chr:FindFirstChild( "LeftFoot" )
		local rightFoot = chr:FindFirstChild( "RightFoot" )
		local upperTorso = chr:FindFirstChild( "UpperTorso" )
		
		leftFoot.Touched:Connect( onTouched( leftFoot ) )
		leftFoot.TouchEnded:Connect( onTouchEnded( leftFoot ) )
		rightFoot.Touched:Connect( onTouched( rightFoot ) )
		rightFoot.TouchEnded:Connect( onTouchEnded( rightFoot ) )
		upperTorso.Touched:Connect( onTouched( upperTorso ) )
		upperTorso.TouchEnded:Connect( onTouchEnded( upperTorso ) )
		print(chr.Name) ---Just used this to see if it works up to here
	end
end

local player = Players.LocalPlayer
-- Check if they already spawned in
if player.Character then
	onCharacterAdded(player.Character)
end
-- Listen for the player (re)spawning 
player.CharacterAdded:Connect(onCharacterAdded)

I left the rest of the script as it was.

hmm, so

  1. Made the changes
local Player = game.Players.LocalPlayer 
local Character = Player.Character
local function onCharacterAdded( chr )
	local hum = chr:WaitForChild( "Humanoid" )
	if hum then
		local leftFoot = chr:FindFirstChild( "LeftFoot" )
		local rightFoot = chr:FindFirstChild( "RightFoot" )
		local upperTorso = chr:FindFirstChild( "UpperTorso" )
		
		leftFoot.Touched:Connect( onTouched( leftFoot ) )
		leftFoot.TouchEnded:Connect( onTouchEnded( leftFoot ) )
		rightFoot.Touched:Connect( onTouched( rightFoot ) )
		rightFoot.TouchEnded:Connect( onTouchEnded( rightFoot ) )
		upperTorso.Touched:Connect( onTouched( upperTorso ) )
		upperTorso.TouchEnded:Connect( onTouchEnded( upperTorso ) )
		print(chr.Name)
	end
end
  1. Placed it on PlayerScripts --works the same as it was in the starter script, and still have the same problem after reset

  2. used WaitForChild , works the same as using the FindFirstChild but still have problem

–prints up to char name but not the hit.Name

Can you attach the place file? As stated I ran this in an empty baseplate with the changes I pasted and it worked every time after resets.

Note: hit name will only be printed if the hit name is sparStage in your example.

Use the code I pasted for you for the entire end section of the script if you’re still having problems, as making changes between what I’ve provided and what you’ve implemented just opens up many more places for issues to occur in your code.

I’ve finally figured it out! The problem was not in the OP code but another script hindering with it which is this code to make the character load as a default block rig:

**Note: I know I did not provide it in the OP, I didn’t think it would be connected to the problem, sorry about that…

local Players = game.Players

function PlayerJoined(Player)
	local function RemoveMeshes(Character)
		local Humanoid = Character:WaitForChild("Humanoid")
		wait()
		local CurrentDescription = Humanoid:GetAppliedDescription() 
		
		CurrentDescription.Head = 0
		CurrentDescription.Torso = 0
		CurrentDescription.LeftArm = 0
		CurrentDescription.RightArm  = 0
		CurrentDescription.LeftLeg = 0
		CurrentDescription.RightLeg = 0
		Humanoid:ApplyDescription(CurrentDescription) 
		
	end
	Player.CharacterAppearanceLoaded:Connect(RemoveMeshes)
end

Players.PlayerAdded:Connect(PlayerJoined)

Now, I only have the problem to make this code work. Anyways, thanks for everyone’s help!

1 Like