Detect if the player leaves or if the character is destroyed via tool script

I’ve had this question alot of times.

I obviously have tried to fix it, It worked, When the character is destroyed, my code goes through, But, When the player leaves, The code doesnt go through.

here is my code:

if Tool.Parent:IsA("Backpack") then
	if Tool.Parent.Parent:IsA("Player") then

		print("Found player")
		if Tool.Parent.Parent.Character ~= nil then
			char = Tool.Parent.Parent.Character
			print("Found player and char.")
			game.Players.PlayerRemoving:Connect(function(playerremove)
				if playerremove == Tool.Parent.Parent then
					print("destroyin")
				
				end
			end)
			Tool.Parent.Parent.Character.Destroying:Connect(function()
				print("destroyin")
				hitbox:Destroy()
			end)
		end
	end
elseif Tool.Parent:IsA("Model") and Tool.Parent:FindFirstChild("Humanoid") then

	print("Found char.")
	Tool.Parent.Destroying:Connect(function()
		print("destroyin ")
	end)
end
Tool.Destroying:Connect(function()
	print("destroyin")
end)

I know its messy, Sorry about that.

This code works for the most part, But if the player leaves, Then it just doesn’t work, the prints for “destroyin” dont appear.

This is very important, As i need this to disable hitboxes (I use spatial queries, I have absolutely no clue how to make them automatically get destroyed when the character leaves, if anyone does, i’d appreciate it alot.)

3 Likes

If I had to guess, the Tool.Parent.Parent instances might be different. Try printing Tool.Parent.Parent.Name on both finding the Player, and removing a player in Studio playtest, and see if they’re the same. If not, try changing removing the second .Parent and see if that changes anything.

1 Like

Sorry for the late response.

This code runs by itself, No functions are called for it to run, Such as Equipped, Or Unequipped, Its just in the middle.

So tool.Parent would be the player backpack (since the tool basically spawns in there) And Tool.Parent.Parent is the player.

Alright, I just tried this, No luck unfortunately, It prints the correct player, But upon removal, Nothing prints at all.
The new script:

		plr = Tool.Parent.Parent
		print(plr.Name)
		print("Found player")
		if Tool.Parent.Parent.Character ~= nil then
			char = Tool.Parent.Parent.Character
			print("Found player and char.")
			game.Players.PlayerRemoving:Connect(function(playerremove)
				print(playerremove.Name)
				if playerremove == plr then
					print("destroyin ")
					hitbox:Destroy()
				end
			end)
			char.Destroying:Connect(function()
				print("destroyin ")
				hitbox:Destroy()
			end)
		end

It seems like the tool is deleted first, But in that case, Is it just impossible for me to remove a spatial query as a hitbox without having to use some weird remote event tricks or something?
I know there are ways to fix this, But, What ive tried seems to not be as performant, and i want this game to be as performant as possible.

Bumping because i really need a solution, I cant continue working on my game if i dont fix this.

Tool.Parent.Parent
gets the Character Model parent not the Player
you have 2 Options
either save the Player’s Instance on a Server Table or use GetPlayerFromCharacter(Character) from the Players Service.
You have another Option which is more Complex which is to save the Entire Player Leaving Function in a Key in a Table on the server and then do the code there checking if they have that tool you want there and then destroy the Hitbox and then Disconnect that Key on the table and make it nil to avoid memory leaks because the player has left so there data is no longer needed

1 Like

No, Because like i stated in a different reply, The code runs at the top of the script, Not when equipped, So tool.parent.parent would indeed be the player, (tool.parent is their backpack)

My problem is not with getting the player/character, Its that i cant detect when they are destroyed.

Explain why u want to use tool as detection of destroyed player or character? Better to use other variants like to get it with server script maybe.

when you equip the actual tool the Tool itself is a Item it is parented to the Character model yes the Backpack is in the player but the Actual tool is give to the Character Model you can check this your self. it does not matter if the Code is at the Top of the Script because the Functions are not saved either way any of my Solutions should work what you are doing will not work and is not safe because Tool.Parent.Parent Changes upon equipping

Because the hitbox variable is created in the tool script (server script) Which creates the hitbox from a module, So i cannot delete it from a different script.

It simply re-parents it, doesn’t create a new one (ive tested this before) So this really doesnt matter.

The code will run when the tool is given to the player’s backpack.

Ive tested it, I have no idea what you mean by “not safe” tools aren’t cloned when a player equips them. So the script stays.

Apologies for this messy reply, What i am looking for is why the destroying function wont work, It detects the player, The character, The backpack, everything, But not when they are destroyed.

So you want the Code to Run when The player leaves and the Tool is Only in their backpack ??

The code is not in the equipped function, If you look at my other replies, you can see that i already used print statements.

So you want the Code to work when The player leaves and the Tool is Only in their backpack ??

What?? No, I want the code to work when the character is destroyed, Doesnt matter where the tool is, these connections have been set up outside of other functions, And i used variables to already set who the player is, So the connections wouldnt change.

All i need is for the code to print “destroyin” when the tool is destroyed (but it wont work when the player leaves. it works when the tool or the character itself is destroyed)

ok ill explain its irrelevant where you put your functions you are not saving them
so the Tool.Parent.Parent it does not save it is changing Constantly when you unequip/ equip so you have to keep things simple get their character and use GetPlayerFromCharacter and destroy thier hitbox like that

Im confused, So does the variable just change on its own??

the Tool.Parent.Parent is Constantly changing so the Connections are also Constantly Changing If you want the Player To be a Constant Then When they join the game thats when you can Open the PlayerLeaving Connection For that Tool currently that Tool.Parent.Parent Can sometimes not return a player Thus the Connections Mess Up. Basically You are not using a constant for the Player

Im not trying to fight. but

This is exactly what im doing.

I really dont want to argue, But i feel like im getting nowhere, I will try these things, But i dont know why you keep telling me to do things ive already done.

have you got a Player Join connection on the server
you can store the Connection within a table or a module Script with there
what you are doing is not correct becuase when the player leaves everything within the Player is destroyed and then the player itself so this connection cannot be a child of the player. the script is also destroyed

Once again, I really dont want to argue, But i was looking more for a solution, And less of someone explaining why it doesn’t work, I know how, I just wanna know how i can fix it.

This seems kind of useless to me, There should be a better way to do this, rather than having to store connections in a seperate script. I’d rather not do this.

Another Solution is to
save the Player Instance when they join via PlayerAdded:connect(Fucntion(player))
and then use that Global Variable to make the Connections within the Tools