π§° Installation
You can install Searcher via:
The source can be found at
π Documentation
Documentation is work in progress. But I have documented some below.
Searcher
Searcher.NewFilter() -> Filter
Searcher.FindOne: (Filter: Filter, Instances: {Instance?}) -> Instance?
Explanation
This can be used to get the first Instance that goes through a filter.
Could for example be used to make a better FindFirstChild() or FindFirstChildWhichIsA().
Example
local Searcher = require(PARENT.Searcher) local NeckFilter = Searcher.NewFilter() :IsA("Motor6D") -- IsA Motor6D? :Named("Neck") -- Named "Neck"? :Not():Property("Part0", nil) -- Has a Part0? :Not():Property("Part1", nil) -- Has a Part1? local Neck: Motor6D? = Searcher.FindOne(NeckFilter, game.Players.Character:GetDescendants())
Searcher.FindAll: (Filter: Filter, Instances: {Instance?}) -> {Instance}
Explanation
This can be used to get all Instances that goes through a filter.
Could for example be used to make a better GetChildren() or GetDescendants().
Example
local Searcher = require(PARENT.Searcher) local VisibleDecalFilter = Searcher.NewFilter() :IsA("Decal") -- IsA Decal? :Not():Property("Transpareny", 1) -- Transparency is NOT 1 -- Get all visible decals in workspace local VisibleDecals: {Decal} = Searcher.FindAll(VisibleDecalFilter, workspace:GetDescendants()) -- Hide the decals by setting Transparency to 1 for _, Decal: Decal in VisibleDecals do Decal.Transparency = 1 end
Searcher.InstanceMatches: (Filter: Filter, Instance: Instance) -> boolean
Explanation
This can be used to check whether a Instance goes through a filter.
Example
local Searcher = require(PARENT.Searcher) local NeonPartFilter = Searcher.NewFilter() :IsA("Part") -- IsA Part? :Property("Material", Enum.Material.Neon) -- Has material set to Neon? print(Searcher.InstanceMatches(NeonPartFilter, MyNormalPart) --> false print(Searcher.InstanceMatches(NeonPartFilter, MyNeonPart) --> true
Searcher.InstanceAdded: (Filter: Filter, Ancestor: Instance?) -> RBXScriptSignal
Explanation
This can be used when you want to detect a new Instance being created that goes through the filter successfully.
Example
local Searcher = require(PARENT.Searcher) local BasePartFilter = Searcher.NewFilter() :IsA("BasePart") -- Detect when a BasePart has been added to workspace Searcher.InstanceAdded(BasePartFilter, workspace):Connect(function(Part: BasePart) print(Part.ClassName) --> BasePart end)
FilterMethods
Explanation
FilterMethods can be chained after creating a Filter to describe if an Instance goes through the filter.
Built in FilterMethods
These are the current built in FilterMethods:
-- Specials
:Not() -- The next chained Filter Method will be inverted (true = false, false = true)
-- Normal
:IsA(ClassName: string) -- Is the object a 'ClassName'?
:Is(Instance: Instance) -- Is the object 'Instance'?
:Named(Name: string) -- Is object named 'Name'?
:Property(PropertyName: string, Value: any) -- Does the object have the property 'PropertyName' set to 'Value'?
:Attribute(AttributeName: string, Value: any) -- Does the object have the attribute 'AttributeName' set to 'Value'?
:Tagged(TagName: string) -- Is the object tagged with 'TagName'?
:ChildOf(Parent: Instance?) -- Is the object a child of 'Parent'?
:DescendantOf(Ancestor: Instance?) -- Is the object a descendant of 'Ancestor'?
:HasChild(Name: string) -- Does the object have a child named 'Name'?
:HasChildWhichIsA(ClassName: string) -- Does the object have a child that IsA 'ClassName'?
:Custom(Callback: (Object: instance) -> boolean?) -- Add a custom callback to the filter, return a boolean that tells Searcher if the object goes through the filter or not.
(If you have any ideas on FilterMethods I could add then please tell me!)
π Usage
The main thing about Searcher is the Filter. To create a Filter you can use the Searcher.NewFilter()
method.
local Searcher = require(PARENT.Searcher)
local Filter = Searcher.NewFilter()
You can apply logic to these filters to distinguish from other instances.
For a Filter to distinguish an Instance as a βvalid instanceβ, all of the passed callbacks (FilterMethods) have to return true.
This is an example of a LavaPart filter.
local LavaFilter = Module.NewFilter()
:IsA("BasePart") -- Is a BasePart
:Tagged("Lava") -- Is tagged with Lava
:DescendantOf(workspace) -- Is descendant of workspace
:Property("Material", Enum.Material.Neon) -- Has the material Neon
:Not():Attribute("Disabled", true) -- Isn't disabled
And the LavaFilter can be used something like this:
-- Get all LavaParts in workspace with the Filter, using the .FindAll function
local LavaParts = Searcher.FindAll(LavaFilter, workspace:GetDescendants())
-- Loop through the parts
for _, Part: Part in LavaParts do
-- Detect collision
Part.Touched:Connect(function(hit)
-- Check if hit is a player
local Humanoid: Humanoid = hit.Parent:FindFirstChildWhichIsA("Humanoid")
if not (Humanoid) then return end
-- Kill player
Humanoid.Health = 0
end
end
Full Script
local Searcher = require(PARENT.Searcher)
local LavaFilter = Searcher.NewFilter()
:IsA("BasePart")
:Tagged("Lava")
:DescendantOf(workspace)
:Property("Material", Enum.Material.Neon)
:Not():Attribute("Disabled", true)
local LavaParts = Searcher.FindAll(LavaFilter, workspace:GetDescendants())
for _, Part: Part in LavaParts do
Part.Touched:Connect(function(hit)
local Humanoid: Humanoid = hit.Parent:FindFirstChildWhichIsA("Humanoid")
if not (Humanoid) then return end
Humanoid.Health = 0
end
end
π Filter Reusage
Filters can be reused infinitely within your code so they are easy to modify and use.
This also means that you can make a ModuleScript that returns a Filter for more organization.
An example of this:
-- CharacterFilter (ModuleScript)
local Searcher = require(PARENT.Searcher)
local CharacterFilter = Searcher.NewFilter()
:IsA("Model")
:HasChildWhichIsA("Humanoid")
return CharacterFilter
π Some Use Case Examples
Here are some Use Case Examples I wrote to show you the power of Searcher.
Getting all Players that are close to the LocalPlayer
local Searcher = require(PARENT.Searcher)
local LocalPlayer: Player = game.Players.LocalPlayer
local ClosePlayersFilter = Searcher.NewFilter()
:IsA("Player") -- Is a Player?
:Not():Property("Character", nil) -- Has a character?
:Not():Is(LocalPlayer) -- Is not the LocalPlayer?
:Custom(function(Player: Player) -- Is Close?
-- Get distance
local Distance: number = (LocalPlayer.Character.HumanoidRootPart.Position - Player.Character.HumanoidRootPart.Position).Magnitude
return (Distance < 40) -- If is close then return true
end)
-- Printing all close Players
print(Searcher.FindAll(ClosePlayersFilter, game.Players:GetChildren()))
π Feedback is Appreciated!
If you have any idea of features I could add or bugs that you find, please tell me, it would really help!
- Yes
- No
- Maybe
- Sometimes
0 voters