Continuous intervals damage script doesn't work

there is no error codes in the output, but the code does not play my sound or deal damage, I’m fairly new to coding so the code may just be flat-out in the wrong format


local radioactiveZone = script.Parent
local damageRate = 3 
local damageInterval = 3 
local playerEntered = {} 


local sound = Instance.new("Sound")
sound.SoundId = "rbxassetid://637072737" 
sound.Volume = 1
sound.Parent = radioactiveZone


local function playSound()
    sound:Play()
end


local function damagePlayers()
    for player, _ in pairs(playerEntered) do
        if player and player.Parent then 
            player:TakeDamage(damageRate) 
        end
    end
end


local function onPlayerEntered(other)
    if other:IsA("Player") then
        playerEntered[other] = true 
        playSound() 
    end
end


local function onPlayerExited(other)
    if other:IsA("Player") then
        playerEntered[other] = nil 
    end
end

radioactiveZone.Touched:Connect(onPlayerEntered)
radioactiveZone.TouchEnded:Connect(onPlayerExited)

while true do
    wait(3)
    damagePlayers()
end 
2 Likes

.Touched returns a Part, not a player

You would have to get the player from the parts parent

local Player = game.Players:GetPlayerFromCharacter(other.Parent)
if player then
playerEntered[other] = true
end

3 Likes

Thanks for clearing that up. However, once inserted into the script, I get the error output
Workspace.Radioactivezone.radioactivity script:6: attempt to index nil with ‘Parent’ \

am I putting it in the wrong place?

It should be placed in your onPlayer(Entered/Exited) functions

2 Likes

Is this spot where you are talking about?

local function onPlayerEntered(other)
    if other:IsA("Player") then
        playerEntered[other] = true 
        playSound() 
		local Player = game.Players:GetPlayerFromCharacter(other.Parent)

		if Player then
			playerEntered[other] = true
		end


    end
end


local function onPlayerExited(other)
    if other:IsA("Player") then
        playerEntered[other] = nil 
    end
end


radioactiveZone.Touched:Connect(onPlayerEntered)
radioactiveZone.TouchEnded:Connect(onPlayerExited)

There are many issues in your script.

function onPlayerEntered(other)

This function is connected to a .Touched event, Touched event does return a BasePart not a Player Instance, as @Sluethen said, you should change this line

if other:IsA("Player") then
    playerEntered[other] = true 
    playSound() 
end

to

if game:GetService('Players'):GetPlayerFromCharacter(other.Parent) then
    playerEntered[game:GetService('Players'):GetPlayerFromCharacter(other.Parent)] = true 
    playSound() 
end

function onPlayerExited(other)

same problem as function onPlayerEntered, you should change

if other:IsA("Player") then
    playerEntered[other] = nil 
end

to

if game:GetService('Players'):GetPlayerFromCharacter(other.Parent) then
    playerEntered[game:GetService('Players'):GetPlayerFromCharacter(other.Parent)] = nil 
end

function damagePlayers()

( I will assume that the functions I said before this are fixed to mine )
So, “playerEntered” table will contain PlayerInstances, also, in for i, v loops, i is for Index, and v is for value.
Which means, you should change this line

for player, _ in pairs(playerEntered) do

to

for _, player in pairs(playerEntered) do

also, TakeDamage is a function of a Humanoid not a Player.
You should change almost entire function from

local function damagePlayers()
    for _, player in pairs(playerEntered) do
        if player and player.Parent then 
            player:TakeDamage(damageRate) 
        end
    end
end

to

local function damagePlayers()
    for _, player in pairs(playerEntered) do
        if player:IsA('Player') then -- incase of different values in table
            local char = player.Character or player.CharacterAdded:Wait()
            char:TakeDamage(damageRate) 
        end
    end
end

a small tip

I wouldn’t recommend using .TouchEnded Event to detect when player’s character left the zone.
It is because TouchEnded event is bit weird, its hard to explain, but it has many problems, you can search about TouchEnded problems in dev forum to see whats the problem of it.

1 Like

Just to nit pick here, you should use the index when referencing the table in pairs in this case if you are seeing the value as true

1 Like

sound is working fine now. The only problem I am struggling with now is the interval damage.

local function damagePlayers()
	for _, player in pairs(playerEntered) do
		if player:IsA('Player') then 
			local char = player.Character or player.CharacterAdded:Wait()
			char:TakeDamage(damageRate) 
        end
    end
end

the output says this:
18:52:41.292 Workspace.Radioactivezone.radioactivity script:24: attempt to index boolean with ‘IsA’ - Server - radioactivity script:24

OMG, sorry.
as @Smojaa said, you should use index instead of value. Im really sorry.

Fixed Code

local function damagePlayers()
	for player, _ in pairs(playerEntered) do
		if player:IsA('Player') then 
			local char = player.Character or player.CharacterAdded:Wait()
			char:TakeDamage(damageRate) 
        end
    end
end
1 Like

all good. The console is now saying 20:30:35.321 TakeDamage is not a valid member of Model “Workspace.W_aev” - Server - radioactivity script:27. However, when I try to define health in takedamage, it will not work. any thoughts?

local function damagePlayers()
	for player, _ in pairs(playerEntered) do
		if player:IsA('Player') then 
			local char = player.Character or player.CharacterAdded:Wait()
			char:FindFirstChild('Humanoid'):TakeDamage(damageRate) 
        end
    end
end
1 Like

awesome! works great! thank you!

moral of the story: Using .Touched on continuous scripts is horribly inefficient and downright broken :slight_smile:

I wish I could give you all a solution :smiling_face_with_tear:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.