How would I make a map border do continuous damage?

I am trying to make a type of world border that will start to slowly deal damage when it is passed, but it only deals damage when the edges are touched. After touching the edge, players can keep walking with no effects afterwards. How do I make the effect continue until the player leaves its radius?

Here’s the script I wrote:

local debounce = false

function onTouched(hit)
        local human = hit.Parent:findFirstChild("Humanoid")
	if (human ~= nil) then
		if not debounce then
			debounce = true
			human.Health = human.Health - 10 -- Change the amount to change the damage.
			wait(3)
			debounce =false
		end
		end
end
script.Parent.Touched:connect(onTouched)
1 Like
debounce = true
wait() -- amount to wait for the damage to effect
human.Health = human.Health - 10 -- Change the amount to change the damage.
wait() -- amount to wait for the damage to effect
human.Health = human.Health - 5 -- Change the amount to change the damage.

I dont fully understand what you mean on what you’re trying to make, but I believe using workspace:GetPartBoundInBox is gonna be alot better for you than the touched event.

The touched event is gonna fire everytime any player touches the part and with each body part,
while with GetPartBoundsInBox it returns a table of all the parts within its zone and then you can filter it and blacklist certain parts you dont wanna detect.

So for example you could do something like every x amount of seconds, for every HumanoidRootPart in the zone, damage the players it belongs to by y amount.

2 Likes

I’m a bit confused by this. You want a border that only damages when touching the wall, but no damage on either side of the border wall?

I want to make a part that players can walk through, but they will take damage while inside it.

I will try that, but what if there are two players touching it? Would it do twice the damage to both of them?

The touched event only fires when another part intially touches it, then it will run the code inside it and move on. This is some code I used awhile ago to create something similar to what I believe you’re trying to create. It will continually damage the player inside variable “killPart” until they leave it. After they leave it, damageConnection will be disconnected, and the player should not take anymore damage. Let me know if it works or not. May have to mess around with how much damage is taken to find out what is right for you.

local killPart = (Path to your part to damage the player)
local canDamage = true

local damageConnection

killPart.Touched:Connect(function(hit)
	print("Kill part touched!")
	if hit.Parent:FindFirstChild("Humanoid") and hit.Parent ~= killPart.Parent.Parent and killPart.Parent.Parent.Humanoid.Health > 0 then
		canDamage = true
		if not damageConnection then
			print("Damage connection not connected")
			damageConnection = RunService.Heartbeat:Connect(function(step)
				if canDamage then
					task.wait(step)
					hit.Parent:FindFirstChild("Humanoid"):TakeDamage(0.5)
				end
			end)
		end
	end
end)

killPart.TouchEnded:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and hit.Parent ~= killPart.Parent.Parent then
		canDamage = false
		if damageConnection then
			damageConnection:Disconnect()
			damageConnection = nil
		end
	end
end)

I am already using option 1, but its acting like you described: as if its just a wall and not a massive part. Thats what I am trying to solve.

I tried it but it doesn’t recognize what RunService is.

That is because RunService is a service. You have to get it through a variable: local RunService = game:GetService(“RunService”)
See if that works. Make sure you put it at the top of your script.

Hello there! This can be really easy made with this module. A simple example to do it for your case would be:

local zone = require(...) -- the location for your zone module
local wallsFolder = ... -- put your walls in a folder and reference them here

local globalChecker = {}

for _, wall in ipairs(wallsFolder:GetChildren()) do
    local zone = Zone.new(wall)

    zone.playerEntered:Connect(function(player)
        globalChecker[player] = true

        local character = player.Character
        local humanoid = character.Humanoid
        task.spawn(function()
            while globalChecker[player] do
                humanoid:TakeDamage(5)
                task.wait(1)
            end
        end)
    end)

    zone.playerExited:Connect(function(player)
        globalChecker[player] = false
    end)
end

Didn’t test this, but pretty sure it will. If someone finds an error, let me know it to correct it!

I will try this out later, thanks for the help!

Oh okay I didn’t know that at first.

Edit: Its displaying errors about the humanoid, saying its not a valid member of DataModel “Game”

What do I put for my zone module? I am guessing you’re talking about the module you linked, but I cant understand why I would need that if I already have a zone in the wall folder.

Hey sorry about that. In the first if statement of the .Touched event (not TouchEnded), remove the last stuff after the last “and”. For my specific script, the killPart was inside the character, however for yours, it’s probably in workspace or something.

Also, next time you get an error please @ me so I know and can respond faster. Thanks.

This is used in combination with your parts for the zone border. Use it and you’ll see. :smiley:

Setup a loop and every 0.5 seconds (or whatever time really) loop through all players and if they’re outside the border then cause damage. If not, do nothing.

Also you probably don’t need to use ZonePlus for something this simple. I guess it depends on the shape of your border though. If you have a square border then use math instead of an entire module. It’s probably better for performance. However if your border is a dome or some other shape then use ZonePlus.

this will reduce the health of every player by 5 that is 100 studs away from 0, 0, 0 every 3 seconds

local center = Vector3.new(0, 0, 0)
local distance = 100
while true do
   for i, player in ipairs(game.Players:GetPlayers()) do
      if player.Character == nil then continue end
      if player.Character.PrimaryPart == nil then continue end
      local magnitude = (center - player.Character.PrimaryPart.Position).Magnitude
      if magnitude < distance then continue end
      player.Character.Humanoid:TakeDamage(5)
   end
   wait(3)
end
1 Like

@1Urge Thanks for the additional instructions. I’m now getting an error about the connect function on line 7. It looks like the functions haven’t been connected to anything yet. I would add the connections myself, but I don’t want to mess anything up.

Which line is line 7 for you? Line 7 for me is the print statement, print("Kill part touched!")