Tag Editor Plugin

This is a plugin for editing CollectionService tags. If you aren’t familiar with what that is, please read the wiki page and then continue reading this post: http://wiki.roblox.com/index.php?title=API:Class/CollectionService

This plugin allows you to create tags, and then assign them to objects in your game. You can also visualize and view a list of what objects have a given tag, and so on. It’s become an essential tool in many game developers’ toolboxes.

Why use CollectionService?

CollectionService allows you to avoid copying and pasting scripts throughout your game and avoid scanning the workspace for hardcoded names. It makes it easy to add scripted behaviors to objects created by level designers on a multi-disciplinary team.

By handling both the added and removed signals in your scripts, it makes it easy to write code that’s compatible with StreamingEnabled.

For example, in the old days someone might implement a kill brick by writing this Script and putting it inside their first kill brick:

script.Parent.Touched:Connect(function(part)
    part:BreakJoints()
end)

Then they would copy and paste that kill brick thousands of times throughout their place. Then they later realize that the brick only breaks your legs off and doesn’t actually kill you when you jump up and down on it, and they want to replace it with this:

script.Parent.Touched:Connect(function(part)
    local humanoid = part.Parent and part.Parent:FindFirstChild("Humanoid")
    if humanoid then
        humanoid.Health = 0
    else
        part:BreakJoints()
    end
end

But now they have a dilemma, that they have thousands of copies of this script that all need to be individually updated. There are a few solutions to this problem today that are used:

  • LinkedScripts, which have the issue that if you ever want to add a ModuleScript child or something, well, you just can’t.
  • Scanning the entire data model for parts named “KillBrick” and attaching code to them, which is slow and is often done without accounting for new bricks being added after the game starts. It also means all of your parts are named after behavioral characteristics (that they kill you) rather than functional ones (hurdles, lava pits, etc.), which some developers further work around by inserting StringValues instead of relying on the part’s name.

CollectionService gets around this in an intuitive way. You’d write this script:

local CollectionService = game:GetService("CollectionService")

function makeKillBrick(part)
    local data = {}

    data.touchedConn = part.Touched:Connect(function(part)
        part:BreakJoints()
    end)

    return data
end

function undoKillBrick(data)
    data.touchedConn:Disconnect()
end

------------------------------------------------------------

local killBricks = {}
local addedSignal = CollectionService:GetInstanceAddedSignal("KillBrick")
local removedSignal = CollectionService:GetInstanceRemovedSignal("KillBrick")
 
local function onAdded(brick)
    killBricks[brick] = makeKillBrick(brick)
end
 
local function onRemoved(brick)
    if killBricks[brick] then
        undoKillBrick(killBricks[brick])
        killBricks[brick] = nil
    end
end
 
for _,brick in pairs(CollectionService:GetTagged("KillBrick")) do
    onAdded(brick)
end
 
addedSignal:Connect(onAdded)
removedSignal:Connect(onRemoved)

Then you can add a new tag to the tag editor like so, which level designers can then assign to objects in the world.

Then, when you realize later that the kill brick chops your legs off instead of actually killing you, you just change that one script.

By doing it this way, you able to dynamically tag and un-tag kill bricks whenever you like, and you can also assign multiple tags to a single part to create compound behaviors.

Note that about half of this snippet is code that can be extracted into a module script and shared between all of your game objects. For fans of OOP, you can also easily reimagine this into an object with a :destroy() method, but I left it out for simplicity of the example. The Maid pattern also works excellently in this scenario.

Features

Completely rewritten

The old plugin was 500 lines in a single script file. The new plugin consists of over 5000 lines of code, and also uses Roact and Rodux.

Totally new UI design

I needed to redo the UI so that it’d work well as a PluginGui when that goes live.

image

When this feature goes live, the plugin will automatically begin using it.

Customizable icons and colors

As you can see in the above screenshot, every tag can have its own icon. These are selected from the FamFamFam Silk icon set, which is the same one used by Studio for the Explorer icons.

Icon Picker

Because the FamFamFam set has over 700 icons in it, I needed to create a nice UI for selecting them. So I created an interface with categories, search, and a preview window.

image

World View

The plugin offers built in visualization by selecting the “World View” button.

image

When you toggle this, it will show objects with tags depending on how you have them configured.

You can configure how each tag renders, with the following options:

  • Selection box (filled or outline only)
  • Floating icon
  • Floating text label
  • Sphere
  • None

You can also quickly toggle a tag on and off by clicking the lightbulb button on the main tag list.

Enabling the world view also makes it so hovering a tagged object with your mouse will create a tooltip showing what tags it has. It also shows the name and class.

image

Color picker

The box and sphere display options display a colored box. As such, there is a color picker so you can select the color to use.

image

Instance view

The instance view shows a list of all of the instances with a given tag, which allows you to quickly select one or more of them. The selection syncs with Studio’s built in object selection.

Groups

Some developers have a bunch of tags that are all related in some way, so there is a grouping feature that allows you organize your tags. The groups can be expanded and collapsed.

image

256 Likes
Add a tag property to all objects
I would like to see examples of Collection Service in use
How Would I decrease Lag In A 100 Player Server
May Recap: Here's What You Might Have Missed in the Developer Community
How to have 1 script reference multiple of the same model
CollectionService behaving weirdly
Justice, the awesome NPC system
How detect if player near light source, so I will be able to Enable Light
Issue With Using CollectionService
Best way to deal with multiple copies of the same script parented to objects
Bloxxer's Studio Development Setup
Best way to organize a game for a level of detail setting
I want to learn about CollectionService and RunService
Tag Tracker Plugin
Fastest and efficient method to detect certain type of cloned parts?
Help With Remote Events
Help With Remote Events
How could i improve my teleporter system
Emancyphur Community Group Information
Performance question related to script(s) & what they can do
Which one would be the best?
Very Long Lighting Code, May Need Shortening
Hey i need help with a monster
How to run this local script on multiple parts?
CollectionService in a nutshell
Automatic on / off street light script
Having issues with a settings gui's function
Re "How to Script Points/Guesses"
Allow us to recolor class icons for organization in Explorer
My game content (models, directories, scripts) is all over the place! But is is a mess? Or is it normal?
DataStore2: How to access the datastore in other scripts
Pathfinding agent stutters after a minute of use
How can I use the same script affect alot of parts?
How to turn all lights off from one button?
Help needed with a coin system
CollectionService in a nutshell
How to make more complicated CollectionService doors?
KillBricks not working
How can I tag stuff with Command Bar?
Rate my DOF code
How does the project format in Rojo compare to the standard format used within studio
How do I get every single part that shares this name?
[V1.1] EzEvent - Event programming simplified
Swimmable part. High performance water
How to make a script that handles multiple Parts?
Is there any way to improve upon my teleporter system
Implementing CollectionService
Wait() for every time the Touch Functions are Called; not working properly [SOLVED]
Are there any limits to Instance:GetDescendants?

This topic was automatically closed after 1 minute. New replies are no longer allowed.