Skip to content

Layer and tag constants

mateusz edited this page Jan 25, 2026 · 1 revision

[assembly: Medicine.GenerateUnityConstants] enables a source generator that reads your Unity project settings and emits a strongly-typed Constants class with:

  • Tags (Constants.Tag)
  • Layers (Constants.Layer)
  • Layer masks (Constants.LayerMask)
  • Convenience extensions for CompareTag and tag handles

Quick start

  1. Define the assembly attribute anywhere in your assembly:
[assembly: Medicine.GenerateUnityConstants]
  1. Apply the "Update project settings" quick fix in your IDE. (Switch to Unity so that the settings are reloaded.)

You can also configure Unity manually by adding -additionalfile:"ProjectSettings/TagManager.asset" to the Additional Compiler Arguments list in Project Settings → Player → Other Settings.

  1. Use the generated types:
public sealed class Example : MonoBehaviour
{
    void Awake()
    {
        // layers
        gameObject.layer = (int)Constants.Layer.Default;

        // layer masks (bit masks)
        var groundMask = Constants.LayerMask.Ground | Constants.LayerMask.Terrain;

        // tags
        if (gameObject.CompareTag(Constants.Tag.Player))
            Debug.Log("Player!");
    }
}

What gets generated

When the generator runs, it emits Medicine.Constants.g.cs containing:

namespace Medicine;

public static partial class Constants
{
    public enum Tag : uint
    {
        @SomeTag = 20000u,
        @AnotherTag = 20001u,
        ...
    }

    public enum Layer : uint
    {
        @Default = 00,
        @TransparentFX = 01,
        @Ignore_Raycast = 02,
        ...
    }

    [System.Flags]
    public enum LayerMask : uint
    {
        None = 0,
        All = 0xffffffff,
        @Default = 1u << 00,
        @TransparentFX = 1u << 01,
        ...
    }

    public static partial class ConstantsExtensions
    {
        public static UnityEngine.TagHandle GetHandle(this Constants.Tag tag)
            => UnsafeUtility.As<Constants.Tag, UnityEngine.TagHandle>(ref tag);

        public static bool CompareTag(this GameObject gameObject, Constants.Tag tag)
            => gameObject.CompareTag(tag.GetHandle());

        public static bool CompareTag(this Component component, Constants.Tag tag)
            => component.CompareTag(tag.GetHandle());
    }
}
  • The generator parses the TagManager.asset file - simply edit layers/tags in Unity, hit Ctrl+S and changes will be instantly reflected in your code.
  • Tags are assigned sequential IDs starting at 20000u. They exist to be stable, typed tokens that can be turned into a TagHandle.
  • Layers are assigned their actual layer index (0..31).
  • LayerMask values are 1u << layerIndex.
  • Names are sanitized into valid C# identifiers:
    • Always prefixed with @ to avoid keyword conflicts.
    • Non-identifier characters become _.
  • Empty entries generate placeholders, allowing you to reference layers that aren't yet defined in the project (e.g., in the inspector).

Comparing tags

The string-based CompareTag(string) has obvious performance and usability flaws. There exists a faster CompareTag(TagHandle) API, but it is a bit annoying to use.

The generator provides:

  • A GetHandle extension method which converts the enum value to a TagHandle.
  • Overloads of CompareTag that accept Constants.Tag, so you can compare against the enum directly.

Practical usage:

if (gameObject.CompareTag(Constants.Tag.Enemy))
{
    // ...
}

This keeps your code:

  • Refactor-safe (rename tags/layers and get compiler errors where you need to update usage)
  • IDE-friendly (autocomplete instead of string literals)
  • Compatible with Unity’s fast tag handle path

Extending the generated class

The generated Medicine.Constants class is partial and lives in your assembly, so you can extend it with your own constants:

namespace Medicine
{
    public static partial class Constants
    {
        public const int MaxPlayers = 4;
    }
}

Troubleshooting

“TagManager.asset not found” (MED018)

If you add [assembly: Medicine.GenerateUnityConstants] but the generator can’t find TagManager.asset as an AdditionalText, it reports MED018:

  • TagManager.asset not found. Your project isn't configured for constants generation.

There is an IDE-side quick fix that lets you fix this in the project settings automatically - just remember to switch to Unity after applying so that the settings are reloaded.

You can also configure Unity manually by adding -additionalfile:"ProjectSettings/TagManager.asset" to the Additional Compiler Arguments list in Project Settings → Player → Other Settings.

“My tag/layer name became @_____

That’s the sanitization step: anything that isn’t a letter/digit/underscore is converted to _, and the name is prefixed with @.

If you want cleaner identifiers, rename the tag/layer in Unity to something C#-friendly (Player, EnemyBoss, UI_Overlay, etc.).

Clone this wiki locally