SimpleZone is a simple(r) alternative to other Zone modules such as ZonePlus.
SimpleZone offers much customizability because of its clean source code and short amount of dependencies.
Documentation:
QueryOptions
The QueryOptions
object is simply something that contains information about how you want the Zone
to query BaseParts, and is used when calling constructors.
You can construct a new QueryOptions
object using SimpleZone.QueryOptions.new()
, or simply just manually making it by using the table constructor {...}
-
QueryOptions.FireMode :: "OnEnter"|"OnExit"|"Both"|"None"
- All this determines is what events will be fired when an item enters or exits the
Zone
.
IfFireMode
is"OnEnter"
, thenZone.ItemExited
will not fire, onlyZone.ItemEntered
.
Same thing for all the otherFireMode
s.
- All this determines is what events will be fired when an item enters or exits the
-
QueryOptions.TrackItemEnabled :: boolean
- This boolean determines wether or not you are able to use
Zone:TrackItem(...)
.
The reason why this needs to exist is because it adds 1 more for loop to the :Update() method, which may be undesirable for people who only want the default behaviour
- This boolean determines wether or not you are able to use
Constructor
The SimpleZone module has 6 constructors, each of which return a Zone
object.
-
SimpleZone.fromPart(part: BasePart, queryOp: QueryOptions)
- This constructor creates a
Zone
using aBasePart
.
If you want yourZone
to respect certain geometries, or if you want yourZone
to be able to move around with aPart
, then use this!
- This constructor creates a
-
SimpleZone.fromBox(cframe: CFrame, size: Vector3, queryOp: QueryOptions?)
- This constructor creates a
Zone
using a bounding box (a CFrame and a Vector3 size!)
If you wanna save more computation time by using workspace:GetPartBoundsInBox() instead of workspace:GetPartsInPart(), then use this!
- This constructor creates a
-
SimpleZone.fromBoxes(boxes: {{cframe: CFrame, size: Vector3}}, queryOp: QueryOptions?)
- If you wish to create a single
Zone
encompassing multiple bounding boxes, this is the constructor you use!
This constructor uses a Bounding Volume Hierarchy structure for optimal efficiency when querying multiple bounding boxes.
- If you wish to create a single
-
SimpleZone.fromCustom(queryFn: (params: OverlapParams?) -> {Instance}, queryOp: QueryOptions)
- If any of the previous constructors didn’t suit your needs, then you can use
SimpleZone.fromCustom(...)
and provide your own custom query function!
Make sure it returns an array ofInstance
s.
- If any of the previous constructors didn’t suit your needs, then you can use
-
SimpleZone.new(...)
- This is the overloaded constructor function that encompasses the first 2 constructor function.
If you don’t wanna waste time typing out all those letters, then use this!
- This is the overloaded constructor function that encompasses the first 2 constructor function.
-
SimpleZone.fromPartParallel(part: BasePart, queryOp: QueryOptions?)
- This constructor is similar to
SimpleZone.fromPart()
, except it constructs a newActor
for dealing with spatial queries.
Due to this, it significantly speeds things up, especially for hundreds ofZone
s!
- This constructor is similar to
And that’s basically all of the constructor functions! Now onto the methods of Zone
itself.
Methods and Callbacks
The Zone
object has quite a number of methods, so lets go through them one by one!
-
Zone:BindToHeartbeat(params: OverlapParams?): ()
- Once you’ve created your
Zone
using one of the 4 constructor functions, make sure to call this method to initiate automatic querying of theZone
!
Otherwise, none of the other things would really work
- Once you’ve created your
-
Zone:UnbindFromHeartbeat(): ()
- This one is self-explanatory, really. It just stops the current heartbeat loop (if any).
Useful if you want to pause theZone
query, maybe for a instakill area that periodically deactivates!
Note that calling this will also clear all stored items inside theZone
.
- This one is self-explanatory, really. It just stops the current heartbeat loop (if any).
-
Zone:ListenTo(datatype: string, mode: "Entered"|"Exited", fn: (item: Instance) -> ()): RBXScriptConnection
- Now, with all this
Zone
query stuff, you probably want to detect when something of a certain ClassNamedatatype
enters/exits theZone
.
And that’s exactly what this method is for!
You can choose iffn
will be called when the item enters or exits with themode
argument.
- Now, with all this
-
Zone:SearchFor(properties: {[string]: "Tag"|any}, mode: "And"|"Or"): {BasePart}
- This is personally my favorite method, it allows you to search the
Zone
forInstance
s matching specific properties!-
mode
argument: What is it?mode
is “And”, then this method will only returnInstance
s that fully match the properties provided.
Otherwise, ifmode
is “Or”, then this method will returnInstance
s that match atleast 1 of the properties provided. -
How is the
Heres the rundown of how you format theproperties
table supposed to be formatted like?properties
table to search for specific attributes, tags, children, parents, etc!
-- properties table example { Parent_Parent_Parent_Name = "Foo" -- Yes, you can recursively search parents! Child1_Child2_Child3_Name = "Bar" -- Yes, you can even recursively search children! SomeProperty = 123 -- This is just for normal properties, like Anchored = true for example. SomeTagName = "Tag" -- If you want to specify that something is a tag, simply change its value to "Tag"! Attribute_SomeAttributeName = "Baz" -- If you want to specify that something is an attribute, simply prefix "Attribute_" before the name! }
-
- This is personally my favorite method, it allows you to search the
-
Zone.Query(params: OverlapParams?): {Instance}
- This is a callback function that will be called anytime any of the
Zone
s methods needs to query theZone
.
You can change this to something else if you wish to update the query part/bounding box, for example!
- This is a callback function that will be called anytime any of the
-
Zone:Update(params: OverlapParams?, onEnter: boolean?, onExit: boolean?): ()
- All this method does is simply update the items of the
Zone
and fire the corresponding events based on the result ofZone.Query()
.
This is the method thatZone:BindToHeartbeat()
calls every heartbeat
- All this method does is simply update the items of the
-
Zone:Destroy()
- If you don’t want a
Zone
to exist anymore (maybe to free up some memory), use this method to completely destroy it!
- If you don’t want a
-
Zone:TrackItem(item: any)
- If a descendant of
item
is found during query,item
is returned instead of the descendant, similar to ZonePlus:trackItem(…).
Note that you need to setTrackItemEnabled
in theQueryOptions
to true for this to work!
- If a descendant of
-
Zone:UntrackItem(item: any)
- Self explanatory xd
And that’s all of the methods covered! I know, quite short, right? Now, onto the events!
Events
The Zone
object only has 2 events, so this should be pretty short!
-
Zone.ItemEntered<Instance>
- This event fires whenever a
Part
orPlayer
is detected entering theZone
, and passes it as an argument to the connected function.
However, this event fires for every type of item that enters. If you wish to narrow it down to eitherPart
s orPlayer
s, then useZone:GetItemSignal(...)
instead!
- This event fires whenever a
-
Zone.ItemExited<Instance>
- Similar to
Zone.ItemEntered
, except when an item exits theZone
!
- Similar to
And that’s all! Now, by now you may be wondering how to use this all together. Well, I’ve put together a section going over use cases for EVERYTHING!
Example Usage
- A biome script!
local Zone = require(path_to_simplezone)
local biomeZone = Zone.fromBox(workspace.Biome.CFrame, workspace.Biome.Size) -- Using a Part here instead of a Model, doesn't affect anything as long as you provide the correct arguments!
biomeZone:BindToHeartbeat()
biomeZone:ListenTo("Player", "Entered", function(player: Player)
player:SetAttribute("Biome", "ThisBiome") -- Setting a Biome attribute on the player to this biome!
end)
biomeZone:ListenTo("Player", "Exited", function(player: Player)
player:SetAttribute("Biome", "None") -- Player has exited the zone, so theyre not in any biome!
end)
- A periodically-disabling instakill area!
local Zone = require(path_to_simplezone)
local QueryOptions = Zone.QueryOptions
-- We only care about the players entering the zone, dead players cant leave! XD
local options = QueryOptions.new()
options.FireMode = "OnEnter"
local killZone = Zone.fromBox(workspace.KillZone.CFrame, workspace.KillZone.Size, options)
killZone:ListenTo("Player", "Entered", function(player: Player)
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
-- KILL THEM >:3
humanoid.Health = 0
end)
while true do
killZone:BindToHeartbeat()
task.wait(10)
-- Disable the zone for 10 seconds!
killZone:UnbindFromHeartbeat()
task.wait(10)
end
- A zone that destroys any parts that come inside it!
local Zone = require(path_to_simplezone)
local QueryOptions = Zone.QueryOptions
-- We only care about the parts entering the zone, because were destroying the parts!!!!
local options = QueryOptions.new()
options.FireMode = "OnEnter"
local killZone = Zone.fromBox(workspace.DestroyZone.CFrame, workspace.DestroyZone.Size, options)
killZone:BindToHeartbeat()
killZone:ListenTo("Part", "Entered", function(part: Part)
part:Destroy() -- DIEEEE
end)
- A zone that kills anyone who exits it!
local Zone = require(path_to_simplezone)
local QueryOptions = Zone.QueryOptions
-- We only care about the players exiting the zone, players who stay inside it are good boys >:3
local options = QueryOptions.new()
options.FireMode = "OnExit"
local roomZone = Zone.fromBox(workspace.RoomBox.CFrame, workspace.RoomBox.Size, options)
roomZone:BindToHeartbeat()
roomZone:ListenTo("Player", "Exited"):Connect(function(player: Player)
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
-- DIEIEEEEE..... AGAIN!!!
humanoid.Health = 0
end)
Hopefully these use cases can help you see how and where to use SimpleZone!
Flaws
Unfortunately, as simple as SimpleZone is, it doesn’t come without its flaws… well, flaw, really.
Because all queries with SimpleZone are done with a .Query function (with no actual volume information being stored inside the Zone itself), that means functions like :findPoint() or :getRandomPoint() in ZonePlus aren’t able to be implemented into SimpleZone.
For the time being, SimpleZone is purely a spatial-querying module.
And that’s all! Let me know if you find any errors/bugs, and happy (late) new yeaaarr!!!
Download SimpleZone now! →
Zone.rbxm (14.0 KB)
Test place download to test the capabilities of SimpleZone →
test.rbxl (109.8 KB)
If you want some more features like :GetRandomPoint() or :IsPointWithinZone(), check out LessSimpleZone, an extension of SimpleZone! →
Was this module useful for you?
- Yes
- No (Please post your reason down in the replies!)
0 voters