Skip to content

Custom Binders

Ivan Murzak edited this page Mar 10, 2026 · 1 revision

Custom Binders

If you need to bind a theme color to a component not covered by the built-in binders, you can create your own in just a few lines of code.

Single-Color Binder

Extend GenericColorBinder<T> where T is the target component type.

using UnityEngine;
using TMPro;

namespace Unity.Theme.Binders
{
    [AddComponentMenu("Theme/TextMeshPro Color Binder")]
    public class TextMeshProColorBinder : GenericColorBinder<TextMeshProUGUI>
    {
        protected override void SetColor(TextMeshProUGUI target, Color color)
            => target.color = color;

        protected override Color? GetColor(TextMeshProUGUI target)
            => target.color;
    }
}

What you need to implement:

  • SetColor(T target, Color color) — Apply the color to your component
  • GetColor(T target) — Return the current color from the component (used for change detection)

What you get automatically:

  • Theme change subscription and unsubscription
  • Alpha override support
  • Editor live preview via [ExecuteAlways]
  • Auto-detection of the target component on Awake()
  • Inspector UI with color dropdown and alpha override toggle

Multi-Color Binder

Extend GenericMultiColorBinder<T> for components that need multiple theme colors (e.g., a component with normal/hover/pressed states).

using UnityEngine;
using UnityEngine.UI;

namespace Unity.Theme.Binders
{
    [AddComponentMenu("Theme/MyComponent Color Binder")]
    public class MyComponentColorBinder : GenericMultiColorBinder<MyComponent>
    {
        protected override string[] ColorEntries => new string[]
        {
            "Primary Color",
            "Secondary Color",
            "Accent Color"
        };

        protected override void SetColors(MyComponent target, Color[] colors)
        {
            target.primaryColor = colors[0];
            target.secondaryColor = colors[1];
            target.accentColor = colors[2];
        }

        protected override Color[] GetColors(MyComponent target)
        {
            return new Color[]
            {
                target.primaryColor,
                target.secondaryColor,
                target.accentColor
            };
        }
    }
}

What you need to implement:

  • ColorEntries — Array of label strings, one per color slot
  • SetColors(T target, Color[] colors) — Apply all colors to the component
  • GetColors(T target) — Return all current colors from the component

Renderer/Material Binder

Extend GenericRendererColorBinder<T> for custom renderer types. This base class already handles material color binding and custom shader property support.

using UnityEngine;

namespace Unity.Theme.Binders
{
    [AddComponentMenu("Theme/MyRenderer Color Binder")]
    public class MyRendererColorBinder : GenericRendererColorBinder<MyCustomRenderer>
    {
        // The base class handles everything for standard material color binding.
        // Override SetColors/GetColors only if you need custom behavior.
    }
}

Required Variant Pattern

To create a Required variant that ensures the target component exists:

using UnityEngine;

namespace Unity.Theme.Binders
{
    [AddComponentMenu("Theme/MyComponent Color Binder (Required)")]
    [RequireComponent(typeof(MyComponent))]
    public class MyComponentColorBinderRequired : MyComponentColorBinder
    {
    }
}

The [RequireComponent] attribute makes Unity automatically add MyComponent when the binder is added, and prevents removing it while the binder exists.

Binder Hierarchy

BaseColorBinder (abstract, [ExecuteAlways])
├── GenericColorBinder<T>             — single theme color → single component
├── BaseMultiColorBinder (abstract)
│   └── GenericMultiColorBinder<T>    — multiple theme colors → single component
│       └── GenericRendererColorBinder<T> — material color with custom property support

Namespace

All binders should be in the Unity.Theme.Binders namespace. The [AddComponentMenu("Theme/...")] attribute ensures they appear under the "Theme/" category in the Add Component menu.

See Also

Clone this wiki locally