What do you want to achieve? Keep it simple and clear!
I’d like to create a script that reduces player health through touch events that fire when any instance found in a table is touched.
What is the issue? Include screenshots / videos if possible!
I can’t find a way to store and reference the parts in a table that I want a touched event to fire when a player steps on 1 of the instances from the table without rendering an error down the line of the player not being found.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I haven’t found anything with a similar title to this topic on this platform.
I can script the touch event fine on instance-to-instance basis, but I’d prefer to have a single script that handles this as there are easily over 200 parts.
The error I’m getting is not stopping the script from running, but it’s annoying when utilising the output for other testing as the for ipairs array keeps going through the loop and failing UNTIL a player actually steps on a block, and then it errors when there is no player to be found.
I thought the script would actually loop through the whole table and wait for the touched event to be fired when the player touches one of the parts in the table before proceeding …but instead it just seems to either be skipping this event or somehow firing it regardless (I am 100% sure that the parts that the player is touching at the runtime are not included in the table)
local parts = game.Workspace["GameObjects[Lethal]"].BasicDamage:GetChildren()
local db = true
local damage = 75
local function calculateDamage(defenceValue)
local damagePercent = damage * defenceValue -- this will find out how much damage to deduct from damage value based on the defence value player has
local damageCalculation = damage - damagePercent -- this will deduct the amount of damage that the player is immune to based on their defence statistic
return damageCalculation
end
for i, damageBlock in ipairs(parts) do
damageBlock.Touched:Connect(function(hit)
local char = hit.Parent
local hum = char:FindFirstChild("Humanoid")
local player = game.Players:FindFirstChild(char.Name)
local levelSelection = player:WaitForChild("levelSelection")
local defenceValue = levelSelection:FindFirstChild("DefenceValue")
if hum and db then
db = false
local resultDamage = calculateDamage(defenceValue.Value)
hum.Health -= resultDamage
task.wait(2) -- THIS DEBOUNCE WILL ONLY WORK ON SINGLE PLAYER, WILL NOT WORK WITH MULTIPLE PLAYERS, EXPLORE WAYS OF DOING THIS (probably requires a table)
db = true
end
end)
end
Hi, I think you forgot to check if player was found.
This should fix the error.
local char = hit.Parent
--local hum = char:FindFirstChild("Humanoid")
-- We don't have to check if the Humanoid exists, because we check if it's a player
-- Every player's character has a Humanoid, unless a cheater destroys it
local player = game.Players:FindFirstChild(char.Name)
if player and db then
db = false
local hum = char.Humanoid
local levelSelection = player:WaitForChild("levelSelection")
local defenceValue = levelSelection:FindFirstChild("DefenceValue")
local resultDamage = calculateDamage(defenceValue.Value)
hum.Health -= resultDamage
task.wait(2) -- THIS DEBOUNCE WILL ONLY WORK ON SINGLE PLAYER, WILL NOT WORK WITH MULTIPLE PLAYERS, EXPLORE WAYS OF DOING THIS (probably requires a table)
db = true
end
I have made the changes you’ve suggested but the error seems to persist,
I have done a quick print statement and it’s not finding the player at all because the touched event is not being triggered (ie the instances from the table are not being touched, so it’s not getting the ‘hit’ instance) yet it proceeds with the logic, which shouldn’t happen as far as I’m aware:
local parts = game.Workspace["GameObjects[Lethal]"].BasicDamage:GetChildren()
local db = true
local damage = 75
local function calculateDamage(defenceValue)
local damagePercent = damage * defenceValue -- this will find out how much damage to deduct from damage value based on the defence value player has
local damageCalculation = damage - damagePercent -- this will deduct the amount of damage that the player is immune to based on their defence statistic
return damageCalculation
end
for i, damageBlock in ipairs(parts) do
damageBlock.Touched:Connect(function(hit)
local char = hit.Parent
local player = game.Players:FindFirstChild(char.Name)
print(player.Name)
local levelSelection = player:WaitForChild("levelSelection")
local defenceValue = levelSelection:FindFirstChild("DefenceValue")
if player and db then
local hum = char:FindFirstChild("Humanoid")
db = false
local resultDamage = calculateDamage(defenceValue.Value)
hum.Health -= resultDamage
task.wait(2) -- THIS DEBOUNCE WILL ONLY WORK ON SINGLE PLAYER, WILL NOT WORK WITH MULTIPLE PLAYERS, EXPLORE WAYS OF DOING THIS
db = true
end
end)
end
local levelSelection = player:WaitForChild("levelSelection")
local defenceValue = levelSelection:FindFirstChild("DefenceValue")
That should fix it.
for i, damageBlock in ipairs(parts) do
damageBlock.Touched:Connect(function(hit)
local char = hit.Parent
local player = game.Players:FindFirstChild(char.Name)
print(player.Name)
if player and db then
local levelSelection = player:WaitForChild("levelSelection")
local defenceValue = levelSelection:FindFirstChild("DefenceValue")
local hum = char:FindFirstChild("Humanoid")
db = false
local resultDamage = calculateDamage(defenceValue.Value)
hum.Health -= resultDamage
task.wait(2) -- THIS DEBOUNCE WILL ONLY WORK ON SINGLE PLAYER, WILL NOT WORK WITH MULTIPLE PLAYERS, EXPLORE WAYS OF DOING THIS
db = true
end
end)
end
You can also do this if you want:
for i, damageBlock in ipairs(parts) do
damageBlock.Touched:Connect(function(hit)
local char = hit.Parent
local player = game.Players:FindFirstChild(char.Name)
if not player then
return
end
print(player.Name)
local levelSelection = player:WaitForChild("levelSelection")
local defenceValue = levelSelection:FindFirstChild("DefenceValue")
if db then
local hum = char:FindFirstChild("Humanoid")
db = false
local resultDamage = calculateDamage(defenceValue.Value)
hum.Health -= resultDamage
task.wait(2) -- THIS DEBOUNCE WILL ONLY WORK ON SINGLE PLAYER, WILL NOT WORK WITH MULTIPLE PLAYERS, EXPLORE WAYS OF DOING THIS
db = true
end
end)
end