Is there any way to efficiently check a player inside a region(a cube or rectangle) every second? I tried Get:TouchingParts, but the touch system is very unreliable on roblox(sometimes doesn’t get picked up). Any help will be appreicated!
while true do
wait()
local Radius = 50
local Pillar = game.Workspace:WaitForChild("Pillar")
local children = workspace:GetChildren()
for i = 1, #children do
local humanoid = children[i]:FindFirstChild("Humanoid")
local root = children[i]:FindFirstChild("HumanoidRootPart")
if root ~= nil and humanoid ~= nil and humanoid.Health > 0 then
local Distance = (root.Position - Pillar.Position).magnitude
print(Distance)
if Distance <= Radius then
local character = game.Workspace:FindFirstChild(children[i].Name)
if character then
local InsideValue = character:FindFirstChild("InsideValue")
if InsideValue then
InsideValue.Value = true
end
end
else
local character = game.Workspace:FindFirstChild(children[i].Name)
if character then
local InsideValue = character:FindFirstChild("InsideValue")
if InsideValue then
InsideValue.Value = false
end
end
end
end
end
end
You can look into the function, FindPartsInRegion3, which is much more reliable than GetTouchingParts.
Thanks for the effort in the help, but .magnitude Is for sphere shapes lol. It starts to become an issue if the player lets say climbs to a large height in the y direction, but is still in the radius gets damages(which is why cube or rectangle is kind of better).
I looked into regions, but haven’t a way to properly incorporate it into the function that I need lol. It’s tough work.
You can run the FindPartsInRegion3 in a while loop, and then check if the parent of that part is a character model and script your code from there
If you want to see if a player is inside a rectangle of a specific shape and orientation you can use an invisible part with this function:
I printed v3 when I tested, and it gave me a Vector3 value, so this is pretty weird lol
It looks like you just have some of the variables mixed up.
local players = game:GetService("Players")
local part = script.Parent
local size = part.Size
local partCFrame = part.CFrame
local function inside(playerPosition)
local v3 = partCFrame:PointToObjectSpace(playerPosition)
return (math.abs(v3.X) <= size.X / 2) and (math.abs(v3.Y) <= size.Y / 2) and (math.abs(v3.Z) <= size.Z / 2)
end
wait(7)
for i = 60, 0, -1 do
for _, player in ipairs(players:GetPlayers()) do
local hum = player.Character and player.Character:FindFirstChild("Humanoid")
local hrp = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
if (hum and hrp and inside(hrp.Position) then
hum:TakeDamage(10)
end
end
end
thanks for the effort in the help, but I copied the exact script, and it still didn’t work aaaa lol even after fixing the parenthesis for (hum and hrp and inside(hrp.Position) ) <–added thisrobloxapp-20201102-1945090.wmv (1013.2 KB)
Are there any errors? A video doesn’t really help with this.
There are 0 errors, but that said the script didn’t do anything.
Oops, I just noticed I forgot to include the wait(1) in the loop, so the whole thing was finishing before you had a chance to test it.
local players = game:GetService("Players")
local part = script.Parent
local size = part.Size
local partCFrame = part.CFrame
local function inside(playerPosition)
local v3 = partCFrame:PointToObjectSpace(playerPosition)
return (math.abs(v3.X) <= size.X / 2) and (math.abs(v3.Y) <= size.Y / 2) and (math.abs(v3.Z) <= size.Z / 2)
end
wait(7)
for i = 60, 0, -1 do
for _, player in ipairs(players:GetPlayers()) do
local hum = player.Character and player.Character:FindFirstChild("Humanoid")
local hrp = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
if (hum and hrp and inside(hrp.Position)) then
hum:TakeDamage(10)
end
end
wait(1)
end
Still doesn’t work my guy lol.
Alternatively you can use a RunService event to make the players take damage continuously instead of hits every second:
local players = game:GetService("Players")
local damageRate = 10 -- HP/second
local part = script.Parent
local size = part.Size
local partCFrame = part.CFrame
local function inside(playerPosition)
local v3 = partCFrame:PointToObjectSpace(playerPosition)
return (math.abs(v3.X) <= size.X / 2) and (math.abs(v3.Y) <= size.Y / 2) and (math.abs(v3.Z) <= size.Z / 2)
end
wait(7)
local timer = 0
local loop
loop = game:GetService("RunService").Stepped:Connect(function(_, dt)
for _, player in ipairs(players:GetPlayers()) do
local hum = player.Character and player.Character:FindFirstChild("Humanoid")
local hrp = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
if (hum and hrp and not inside(hrp.Position)) then
hum:TakeDamage(damageRate * dt)
end
end
if (timer >= 60) then
loop:Disconnect()
else
timer = timer + dt
end
end)
modified ur script a little, and finally got the result that I wanted(runservice is a little quick)! I still have no idea why your previous scripts didn’t work though as are literally the same. Thank you for all your dude I appreciate it! Here’s the final:
local players = game:GetService(“Players”)
local damageRate = 10 – HP/second
local part = script.Parent
local size = part.Size
local partCFrame = part.CFrame
local function inside(playerPosition)
local v3 = partCFrame:PointToObjectSpace(playerPosition)
return (math.abs(v3.X) <= size.X / 2) and (math.abs(v3.Y) <= size.Y / 2) and (math.abs(v3.Z) <= size.Z / 2)
end
wait(7)
local timer = 0
local loop
for i = 60, 0 , -1 do
for _, player in ipairs(players:GetPlayers()) do
local hum = player.Character and player.Character:FindFirstChild(“Humanoid”)
local hrp = player.Character and player.Character:FindFirstChild(“HumanoidRootPart”)
if (hum and hrp and not inside(hrp.Position)) then
hum:TakeDamage(damageRate)
end
end
if (timer >= 60) then
loop:Disconnect()
else
wait(1)
timer = timer + 1
end
end
If you have the time can you explain what :PointToObjectSpace() does? I really like understanding scripts, and not just freeloading them. If not that’s fine as well. Thanks for everything! Your method was genius(especially with that math.abs(), and size/2 method. I would never think of that.
CFrame:PointToObjectSpace(Vector3) gives you Vector3’s position relative to CFrame. That way if the resulting vector is inside the bounds of the part defined by the part’s size, then we know that the position is inside the part.