Last active
October 31, 2023 20:02
-
-
Save Fraktality/4e394945c865263144263250d5a78f79 to your computer and use it in GitHub Desktop.
Fast trigger volumes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local RunService = game:GetService("RunService") | |
-- compile an oriented bounding box into a scaled CFrame | |
local function compileBBox(cframe: CFrame, size: Vector3) | |
return CFrame.fromMatrix( | |
cframe.Position, | |
cframe.XVector/size.X, | |
cframe.YVector/size.Y, | |
cframe.ZVector/size.Z | |
):Inverse() | |
end | |
-- point-obb occupancy test | |
local function testPointBBox(pt, bbox) | |
local objPos = bbox*pt | |
return | |
math.abs(objPos.X) < 0.5 and | |
math.abs(objPos.Y) < 0.5 and | |
math.abs(objPos.Z) < 0.5 | |
end | |
local function initZone(zoneRoot, pointCallback, enterCallback, exitCallback) | |
local bboxData = zoneRoot:GetChildren() | |
for idx, part in bboxData do | |
bboxData[idx] = compileBBox(part.CFrame, part.Size) | |
end | |
-- check bounds to select initial callback | |
local lastCallback = exitCallback do | |
local pt = pointCallback() | |
for _, bbox in bboxData do | |
if testPointBBox(pt, bbox) then | |
lastCallback = enterCallback | |
break | |
end | |
end | |
end | |
lastCallback() | |
-- use heartbeat to run after physics solve, prior to render | |
return RunService.Heartbeat:Connect(function() | |
local pt = pointCallback() | |
if not pt or pt ~= pt then | |
return -- ignore nan, nil | |
end | |
local sel = exitCallback | |
-- select a callback | |
for _, bbox in bboxData do | |
if testPointBBox(pt, bbox) then | |
sel = enterCallback | |
break | |
end | |
end | |
-- dedup and run callback | |
if sel ~= lastCallback then | |
lastCallback = sel | |
sel() | |
end | |
end) | |
end | |
-- usage | |
initZone( | |
game:GetService("ReplicatedStorage").SoundZone1, -- folder of parts | |
function() -- character's position | |
return workspace.CurrentCamera.Focus.Position | |
end, | |
function() -- entry callback | |
print("entered SoundZone1") | |
end, | |
function() -- exit callback | |
print("exited SoundZone1") | |
end, | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment