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

187 Likes

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