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 "Float Value" or "Random Float"), 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 type picker 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
 
IFloatValue
(None)
Float Value
Asset
Math
Context
Data Storage
Input
Lookup
Spatial
Time
Classic picker (the default): categories open to the side, one line per entry.
Type to search every category…
All / Lookup
Float At Condition
Picks a number based on which condition is true.
Float At Index
Picks one number from a list by index.
Detailed picker: one category at a time, each entry with its full description.
Detection Strategy(None)◎
Before: the field is empty.
Detection StrategyTrigger & Collision
After: the pill names the picked type. Unfold the row to set it up.

Tip

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

Picker styles

The type picker comes in two visual styles, switchable in Project Settings → Jungle → Type Picker:

  • Classic (AdvancedDropdown) (default) — Unity's built-in cascading dropdown. Zero dependencies, available on every Unity version. Compact, with a search field at the top; long descriptions are clipped to a single line.
  • Detailed — a popup that browses the same types one category at a time, with each entry's full description shown under its name. Typing searches every category at once. No extra package needed.

Both styles list the same types with identical categories, descriptions, and filtering — only the presentation differs.


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
EmptyLabel (None) Text shown while the field is empty

List options (UniqueTypes, Layout) live on [JungleList], see Lists of Selectable Types.

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
Order No Named property — sort hint for the popup. Lower appears first; unset sorts to the alphabetical tail

Ordering the Popup

By default the popup is fully alphabetical: categories by name, entries by display name. To surface the obvious choices first, set the Order named property on [JungleClassInfo]. Lower numbers appear first; entries that share an order (or leave it unset) fall back to alphabetical order. You only need to number the few entries you want at the top — everything else keeps sorting alphabetically below them.

[JungleClassInfo("A constant float value", null, "Math", Order = 0)]  // floats to the top
[Serializable]
public class ConstantFloat : IValue<float> { /* ... */ }

Categories float up with their members. A category's position is driven by the lowest Order among everything inside it. So numbering a single obvious entry pulls its whole category to the top of the list — you never order categories directly, you order the entries and the grouping follows.

Uncategorized entries interleave with category folders. Loose entries (no category) and category folders are ordered together by their effective order, not "all folders, then all loose entries." So an inline Order = 0 value with no category sits at the very top, above a folder whose best member is Order = 1. This is why the obvious top-level picks surface first even when most other options are tucked into folders.

// "Math" jumps above "Spatial"/"Physics" because its best entry is Order = 0,
// even though "M" sorts after them alphabetically.
[JungleClassInfo("Add two floats", null, "Math", Order = 0)]
public class AddFloat : IValue<float> { /* ... */ }

Both picker styles (AdvancedDropdown and the detailed window) and the toggle-set list all consume the same ordering, so the result is identical everywhere.


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]
[JungleList(UniqueTypes = true)]
private List<IMyBehavior> behaviors = new();

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

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

[SerializeReference]
[JungleList(Layout = JungleListLayout.ToggleSet)]
private List<IMyBehavior> behaviors = new();
Steps2+
Step 1Simple Step
Labelsimple
Amount1
Step 2Simple Step
Regular list: add any type, as many times as you like, in any order.
Simple Step
Labelsimple
Amount1
Scale Step
Composite Step
Toggle set: every type is listed once. Tick the ones you want.

Summary

flowchart LR
    A["[SerializeReference] field"] --> B["[JungleClassSelection] attribute"]
    B --> C["TypeSelectableField in Inspector"]
    C --> D["Click type button"]
    D --> E["Type picker 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.