Skip to content

Value Providers

The Core Idea

Instead of hardcoding a speed, a position, or a color, make it configurable - the user picks the source in the Inspector.

A speed can be a constant number for prototyping, an animation curve that ramps up over time, an Animator parameter driven by state machines, or a shared asset that multiple objects read from. The component using the speed does not care which - it just asks for the current value and gets a number back.

This is what value providers do: they separate what a value is from where it comes from. You configure the source in the Inspector by picking from a popup menu, and the component works with any source you choose.

Example use cases:

  • A movement speed that starts constant but later switches to an animation curve for polish
  • A target position that can come from a Transform, a spline point, or a raycast hit
  • A color that reads from a gradient, a material property, or a shared palette asset

How It Looks in the Inspector

A value provider field shows the currently selected source (e.g., "Constant Float"). Click it to switch to a different source. Expand the foldout to configure that source's settings.

For a float value, you might see options like:

  • Constant Float - A single number field
  • Animation Curve Float - A curve editor and time source
  • Transform Distance - Two Transform references and a distance mode
  • Random Range - Min and max fields

Practical Example

Consider a modifier that moves an object at a configurable speed. Without value providers:

// Hardcoded — speed is always a literal number
[SerializeField] private float speed = 5f;

With value providers:

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

void Update()
{
    transform.position += transform.forward * speed.Value() * Time.deltaTime;
}

Now the user can configure speed in the Inspector to come from:

  • A constant (5.0) for simple cases
  • An AnimationCurve that ramps up over time
  • An Animator float parameter driven by animation state
  • A ScriptableObject shared across multiple objects
  • A Random range for variety

The code does not change. Only the Inspector configuration does.


Data Flow

flowchart LR
    subgraph Sources
        A[Constant]
        B[Transform]
        C[ScriptableObject]
        D[AnimationCurve]
    end
    E["IValue&lt;float&gt;"]
    F[Consumer Component]
    A --> E
    B --> E
    C --> E
    D --> E
    E -->|"Value()"| F

The consumer only knows about the value interface. The concrete source is selected by the user in the Inspector through the class selection system.


Technical Details

IValue<T>

The read-only value provider. This is the interface you will encounter most often.

public interface IValue<out T>
{
    T Value();
}
Member Description
Value() Returns the current value
V Shorthand property — equivalent to Value()
Initialize() Called once when the value source is first used in a pipeline
HasMultipleValues Whether this provider can return more than one value
GetValueAt(int index) Access individual values for multi-value providers

ISettableValue<T>

Extends IValue<T> with write access. Used for two-way bindings where the consumer needs to push values back.

public interface ISettableValue<T> : IValue<T>, IValueApplier<T>
{
    void SetValue(T value);
}

IValueApplier<T>

Applies a value to a target. Used by pipelines to write the final computed value to its destination (e.g., setting a Transform's position).

public interface IValueApplier<T>
{
    T CurrentValue { get; }
    void Apply(T value);
    void Initialize();
    void Complete();
}

Common Value Types

Value providers exist for every common Unity type, spread across Jungle packages:

Type Package Example Sources
float jungle.math Constant, AnimationCurve, Animator parameter, Random range
int jungle.math Constant, counter, database lookup
double jungle.math Constant, high-precision calculations
Vector3 jungle.spatial Constant, Transform position, spline point
Quaternion jungle.spatial Constant, Transform rotation
Color jungle.graphics Constant, material property, gradient sample
bool jungle.core Constant, toggle state
string jungle.core Constant, localization key
GameObject jungle.objects Direct reference, find by tag/name
Component jungle.objects Direct reference, GetComponent lookup
Rigidbody jungle.physics Direct reference, velocity accessor

Value Sources

For any given type, multiple source implementations exist. Here are the common patterns:

Constant

The simplest provider. Returns a serialized value directly. Good for prototyping or when the value truly is fixed.

From Transform

Reads a value from a Transform component — position, rotation, scale, or a derived quantity like forward direction.

From Component Property

Reads a property from any component. For example, a Rigidbody's velocity magnitude as a float value.

From ScriptableObject

Reads from a shared ScriptableObject asset. Useful when multiple objects need to reference the same configurable value.

From Function

Computes the value dynamically. Wraps a delegate or expression — useful for math operations, remapping, or aggregating other values.