Touch/Overlap/Zone module

This is my first-ever module script that I’m dropping on the DevForum. This module script does the job of spotting when one part colliding or overlaping with another part using the workspace:GetPartBoundsInBox() trick and Object-Oriented Programming (OOP) technique. I’m still kinda new to this whole OOP thing and totally up for digging deeper. So, if you’ve got any cool suggestions or thoughts, I’m all ears!

local rs = game:GetService("ReplicatedStorage")

local zone = {}
zone.__index = zone

function zone:setupOverlapParams()
	self.param = OverlapParams.new()
	self.param.FilterType = Enum.RaycastFilterType.Include
	self.param.MaxParts = 10
end

function zone:checkPartTouching(part :BasePart)
	if not self.colliders then warn("No collider registered") return end
	if #self.colliders == 0 then return end

	self.param.FilterDescendantsInstances = self.colliders
	return workspace:GetPartBoundsInBox(part.CFrame,part.Size,self.param)
end

function zone:assignColliders(colliders :{BasePart})
	if typeof(colliders) ~= "table" then warn("Colliders must be a table") return end
	
	self.colliders = colliders
end

function zone:addCollider(parts :{BasePart})
	if not self.colliders then self:assignColliders({}) end
	
	for _,part in pairs(parts) do
		table.insert(self.colliders,part)
	end
end

function zone.new()
	local self = setmetatable({},zone)
	
	self:setupOverlapParams() --// self.param
	
	return self
end

return zone

Example

local sss = game:GetService("ServerScriptService")
local zoneModule = require(sss.Libs.ZoneModule)

local collidersFolder = workspace.CollidersFolder
local somePart = workspace.SomePart

local colliders = {}

for _,v in pairs(collidersFolder:GetChildren()) do
    table.insert(colliders,v)
end

local zone = zoneModule.new()
zone:addCollider(colliders)

local overlappingParts = zone:checkPartTouching(somePart) --RESULT

By making a few modifications, we can implement touch detection that operates at a 1.5-second interval. Here’s an example of touch detection in my train game, where I’m detecting the locomotive’s main part as it touches a designated station zone.

while task.wait(1.5) do
    for mainPart :BasePart, collidingParts :{BaseParts} in pairs(locosMainPart) do
        local overlappingParts = zone:checkPartTouching(mainPart)
        
        for _,part in pairs(collidingParts) do --// LOCO EXITED EVENT (COMPARING TABLE 1 AND TABLE 2)
            
            local index = table.find(overlappingParts,part)
            
            if index then continue end
            
            local exitedLocoMainPart = mainPart
            local exitedFrom = part
            rs.Remotes.LocoExited:Fire(exitedLocoMainPart,exitedFrom)

        end
        
        if #overlappingParts == 0 then
            locosMainPart[mainPart] = overlappingParts
            continue
        end
        
        for i,part in pairs(overlappingParts) do --// LOCO ENTERED EVENT (COMPARING TABLE 2 AND TABLE 1)
            
            local index = table.find(collidingParts,part)
            
            if index then continue end
            
            local enteredLocoMainPart = mainPart
            local enteredTo = part
            rs.Remotes.LocoEntered:Fire(enteredLocoMainPart,enteredTo)
        end
        
        locosMainPart[mainPart] = overlappingParts
        
    end
end
1 Like