Hey! I’m trying to create a PlayerLeft event (basically when the player leaves the region/zone), which is the opposite of PlayerEntered. I’m creating my own Zone module so I can learn, but I’m trying to figure out on detecting when the PlayerLeft. I’m quite stumped.
Also, if you have any tips on how to optimize this code, please leave some!
--!nonstrict
local module = {}
module.__index = module
local Janitor = require(script.Janitor)
local FastSignal = require(script.FastSignal)
local PlayerService = game:GetService("Players")
local RunService = game:GetService("RunService")
local HttpService = game:GetService("HttpService")
local Zones = {}
export type Zone = {
_Janitor : any,
Container : BasePart,
Touched : RBXScriptSignal,
PlayerEntered : RBXScriptSignal,
PlayerExited : RBXScriptSignal,
ZoneID : string
}
local function round(number, decimalPlaces)
return math.round(number * 10^decimalPlaces) * 10^-decimalPlaces
end
function findPlayer(zone: Zone, player: Player)
for _, v in pairs(workspace:GetPartsInPart(zone.Container)) do
local Player = PlayerService:GetPlayerFromCharacter(v.Parent)
if Player then
return true
else
return nil
end
end
end
function module.new(container: BasePart)
local Zone: Zone = {}
local Players = {}
setmetatable(Zone, module)
local Janitor = Janitor.new()
local PlayerEntered: any = FastSignal.new()
local PlayerExited: any = FastSignal.new()
local Touched: any = FastSignal.new()
Zone.Container = container
Zone.Touched = Touched
Zone.PlayerEntered = PlayerEntered
Zone.PlayerExited = PlayerExited
Zone.ZoneID = HttpService:GenerateGUID()
Zone._Janitor = Janitor
local updated = Janitor:Add(
FastSignal.new()
)
local triggerTypes = {
"Touched",
"Player"
}
local triggerEvents = {
"",
"Entered",
"Exited"
}
table.insert(Zones, Zone)
RunService.Heartbeat:Connect(function()
local TouchingParts = workspace:GetPartsInPart(Zone.Container)
for _, TouchingPart in pairs(TouchingParts) do
Touched:Fire(TouchingPart)
local Player = PlayerService:GetPlayerFromCharacter(TouchingPart.Parent)
if Player then
Players[Player] = Player
PlayerEntered:Fire(Player)
end
for _, plr in pairs(Players) do
if findPlayer(Zone, plr) == nil then --[[ IF THE]]
--print("PLAYER REALLY DID EXIT OMG")
PlayerExited:Fire(plr)
table.remove(Players, table.find(Players, plr))
else
end
end
end
end)
return Zone
end
function module:findPlayer(player: Player)
for _, v in pairs(workspace:GetPartsInPart(self.Container)) do
local Player = PlayerService:GetPlayerFromCharacter(v.Parent)
if Player then
return Player
else
return nil
end
end
end
function module.fromRegion(cframe, size)
local container = Instance.new("Part")
container.CFrame = cframe
container.Size = size
return module.new(container)
end
function module:GetZoneFromID(GUID: string)
for _, zone in pairs(Zones) do
if zone.ZoneID == GUID then
return zone
end
end
end
function module:GetID(zone: Zone)
return zone.ZoneID
end
function module:Delete()
self._Janitor:Destroy()
end
return module