Script that checks if player has died from void isn't working

  1. What do you want to achieve? Keep it simple and clear!

If a player throws a player into the void after grabbing them then the player who threw will earn points.

  1. What is the issue? Include screenshots / videos if possible!

It just isn’t working, no errors or anything. I put a print() everywhere to check if they are working; the while loop that executes the function is working, but the function itself is not.
The problem seems to be at Line 10, but I’m sure it is the entire function that doesn’t work.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I didn’t really know what to search on the Developer Hub/Devforum. I tried removing Line 10 and making it an if statement rather than a event connection both ended up breaking and lagging out my game.
I didn’t know what else to do since I took this code from a person who replied to my post a few months ago.

Code:

local players = game:GetService("Players")

local grabTag = Instance.new("StringValue", game.ServerStorage)
grabTag.Name = "lastGrabbed"

local function CheckInVoid(killed, killer)
local killedPlayer = players:GetPlayerFromCharacter(killed)
local receivedBounty = false
if players:FindFirstChild(killer) then
	killed.Torso:GetPropertyChangedSignal("Velocity"):Connect(function() -- line 10; this is the problem
		if killed.Torso.Position.Y >= -400 then
			if killed.Humanoid.Health <= 0 and receivedBounty == false then
				receivedBounty = true
				if killer:FindFirstChild("leaderstats") and killer.leaderstats:FindFirstChild("Bounty") and killedPlayer:FindFirstChild("leaderstats") and killedPlayer.leaderstats:FindFirstChild("Bounty") then
					local killerbounty = killer.leaderstats.Bounty
					local killedbounty = killedPlayer.leaderstats.Bounty
					killerbounty.Value = killerbounty.Value + (20 + killedbounty.Value)
					killedbounty.Value = 0
				end
			else
				if killed.Humanoid:GetState() == Enum.HumanoidStateType.Landed then
					receivedBounty = false
					return
				end
			end
		end
	end)
end
end

players.PlayerAdded:Connect(function(plr)
	local lastGrabbed = grabTag:Clone()
	lastGrabbed.Parent = plr
	plr.CharacterAdded:Connect(function(char)
		while game.Workspace:FindFirstChild(char.Name) do
			CheckInVoid(char, lastGrabbed.Value)
			wait()
		end
	end)
end)

I know there’s a lot of ways to make my code more efficient.
I’m going to optimize all of my scripts on a later date, so I apologize to all of the advanced programmers that had to read that. :sweat_smile:

Instance:GetPropertyChangedSignal no longer works with physics related properties.

You can instead connect a loop to check when the player has fallen Humanoid.FreeFalling and loop checking the Position.Y until the player has landed or died.

In your case however, the loop should be stopped until the Parent of the killed player becomes nil.

1 Like

I’ll try this out, but before I do, what’s the difference between Humanoid.FreeFalling and Humanoid.FallingDown?

Edit: Nevermind, I just searched up the difference. Humanoid.FreeFalling worked, thanks.

When a player dies in the void, only the Humanoid (and probably scripts IIRC) stay in the character model so you could just check for the rootpart or a limb and that might be the way for you to check if a player died in the void.

Another way I can think of is to have an object connected to the torso but not as a child without getting removed after death and reading off it on the death event to see what the Y value was.

2 Likes

When a player dies in the void, only the Humanoid (and probably scripts IIRC) stay in the character model so you could just check for the rootpart or a limb and that might be the way for you to check if a player died in the void.

Ah, that’s why the Character.Torso was becoming nil.
You said that only the Character.Humanoid stayed after a player dies in the void, so I don’t know why you said that I should check for the other limbs’ positions as it would turn out with the same result.

Another way I can think of is to have an object connected to the torso but not as a child without getting removed after death and reading off it on the death event to see what the Y value was.

How exactly should I do this? I get what you mean but I don’t know I would go about doing it.

Updated Code:

local players = game:GetService("Players")

local grabTag = Instance.new("StringValue", game.ServerStorage)
grabTag.Name = "lastGrabbed"

local function CheckInVoid(killed, killer)
	local receivedBounty = false
	local killerPlayer = players:FindFirstChild(killer)
	if killerPlayer then
		if killed.Character:FindFirstChild("Torso").Position.Y <= -400 then
			if killed.Humanoid.Health <= 0 and receivedBounty == false then
				receivedBounty = true
				if killer:FindFirstChild("leaderstats") and killer.leaderstats:FindFirstChild("Bounty") and killed:FindFirstChild("leaderstats") and killed.leaderstats:FindFirstChild("Bounty") then
					local killerbounty = killer.leaderstats.Bounty
					local killedbounty = killed.leaderstats.Bounty
					killerbounty.Value = killerbounty.Value + (20 + killedbounty.Value)
					killedbounty.Value = 0
					receivedBounty = false
				end
			else
				receivedBounty = false
				return
			end
		end
	end
end

players.PlayerAdded:Connect(function(plr)
	local lastGrabbed = grabTag:Clone()
	lastGrabbed.Parent = plr
	plr.CharacterAdded:Connect(function(char)
		char:FindFirstChild("Humanoid").FreeFalling:Connect(function()
			CheckInVoid(plr, lastGrabbed.Value)
		end)
	end)
end)

I changed it to Character.Humanoid.FreeFalling because of @Feedekaiser and it worked. I also fixed how it gets the killer’s player instance.

The only problem now it seems is how the script can’t find the Character.Torso instance after your character has died since all of the players body parts + the HumanoidRootPart are destroyed when you die from the void, like what @ArtFoundation said. I could reorder the if statements, but I don’t really know.

1 Like

Adding onto the Torso disappearing when you die from the void, how about instead of checking for the Y height, you can simply just check for if the player’s missing a HumanoidRootPart with FindFirstChild?

1 Like

I don’t understand. I’m checking for the Y height of the Torso so that the script can know if the player has reached the void. Did you mean to check if the player is missing a HumanoidRootPart before checking for the Torso’s Y position?
If so, I think you’d have to reorder the if statements, but again, I don’t really know.

2 Likes

If the player loses all of the parts in their character model when they hit the void, then that would mean that the rootpart would disappear-- basically eliminating the need to check for the character’s Y height altogether. Essentially, you’d be letting the game handle knowing if the player’s reached the void for you. The only issue with this method would be if you have something in your game that deletes a player’s root part, then it would technically also be ‘reaching the void’, at least to the code.

Basically:
Character reaches the void, loses all parts and dies
Code checks if there’s a HumanoidRootPart in the character
If not, then award the bounty

3 Likes

Ah, I understand. I’ll try this out.

Edit: It worked! :grinning:

1 Like

The second one is just an idea and I have not actually tested it. You would just make sure the part isn’t in the character so it isn’t deleted and you could use a weld.

I would recommend trying the first method as it actually has been tested by me. You can try something like this:

local function isInVoid()
    return humanoid.RootPart ~= nil
end
1 Like