Skip to content

The Class Selection System

Pick any behavior from a searchable, categorized popup - no code needed. Whether you are choosing a value source, a process, a condition, or an event, the workflow is always the same: click the type button, browse or search, and select the one you want.

This is how Jungle makes complex components configurable. Instead of hardcoding which behavior a field uses, the field offers a menu of every compatible option, organized by category and annotated with descriptions. You pick the right one for your situation, and the Inspector shows its settings inline.


How It Works in the Inspector

When you see a field displaying a type name (like "Constant Float" or "Transform Position"), that is a TypeSelectableField powered by the class selection system. Here is the interaction flow:

Step by Step

  1. Click the type name button — The ClassSelectionWindow popup opens
  2. Browse categories — Implementations are grouped by category (e.g., "Math", "Spatial", "Physics"). Categories are defined by the implementation author.
  3. Read descriptions — Each entry shows a description and optional icon to help you understand what it does
  4. Select a type — Click an entry to assign it to the field
  5. Configure properties — Expand the foldout to see and edit the selected type's serialized fields

Tip

The popup supports keyboard navigation and filtering. Start typing to filter the list by name.


Under the Hood

The class selection system is powered by two attributes that work together:

  1. [SerializeReference] - Unity's built-in attribute that enables polymorphic serialization (storing different types in the same field)
  2. [JungleClassSelection] - Jungle's attribute that replaces the default rendering with a categorized popup

Without these, Unity would either show nothing or show a raw dropdown of fully qualified type names with no descriptions, no categories, and no icons.

Key Attributes

JungleClassSelectionAttribute

Applied to a field alongside [SerializeReference]. This is what triggers the custom Inspector rendering.

[SerializeReference]
[JungleClassSelection]
private IValue<float> speed;

Options:

Property Default Description
BaseType Field type Override the base type used to populate the selection menu
UniqueTypes false For lists: exclude types already used by other elements
Foldable true For lists: whether the list has a foldout header
ToggleSet false For lists: render as a flat set of toggle rows instead of a growable list

JungleClassInfoAttribute

Applied to a class (the implementation) to control how it appears in the selection popup.

[JungleClassInfo("A constant float value", "Icons/constant", "Math")]
[Serializable]
public class ConstantFloat : IValue<float>
{
    [SerializeField] private float value;
    public float Value() => value;
    // ...
}

Parameters:

Parameter Required Description
description Yes Text shown in the selection popup
iconPathOrKey No Icon path or localization key for the popup icon
category No Grouping category in the popup (e.g., "Math", "Spatial")
displayName No Override the type name shown in the popup
drawInline No Whether the type renders inline in the Inspector

Creating Your Own Selectable Type

To make a new type appear in the class selection system:

1. Define an interface (or use an existing one)

public interface IMyBehavior
{
    void DoSomething();
}

2. Implement it with metadata

[Serializable]
[JungleClassInfo("Logs a message to the console", "Icons/log", "Debug")]
public class LogBehavior : IMyBehavior
{
    [SerializeField] private string message = "Hello";

    public void DoSomething()
    {
        Debug.Log(message);
    }
}

3. Use it in a component

public class MyComponent : MonoBehaviour
{
    [SerializeReference]
    [JungleClassSelection]
    private IMyBehavior behavior;
}

The Inspector will now show a TypeSelectableField for behavior. Clicking it opens the class selection popup, which lists LogBehavior under the "Debug" category with the description "Logs a message to the console."

Don't forget [Serializable]

Every class used with [SerializeReference] must be marked [Serializable]. Without it, Unity cannot serialize the instance and the field will silently reset to null.


Lists of Selectable Types

When the field is an array or List<>, the class selection system renders a JungleList with per-element type picking:

[SerializeReference]
[JungleClassSelection(UniqueTypes = true)]
private List<IMyBehavior> behaviors = new();

With UniqueTypes = true, the add button hides types that are already in the list, preventing duplicates.

With ToggleSet = true, the list renders as a flat set of rows — one per available type — with checkboxes to enable or disable each:

[SerializeReference]
[JungleClassSelection(ToggleSet = true)]
private List<IMyBehavior> behaviors = new();

Summary

flowchart LR
    A["[SerializeReference] field"] --> B["[JungleClassSelection] attribute"]
    B --> C["TypeSelectableField in Inspector"]
    C --> D["Click type button"]
    D --> E["ClassSelectionWindow popup"]
    E --> F["[JungleClassInfo] metadata"]
    F --> G["Categories, icons, descriptions"]

The class selection system is the backbone of Jungle's Inspector experience. Every value provider, process, condition, event, and modifier uses it. Once you are comfortable with the click-to-select-type workflow, you can configure any Jungle component.