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:
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<float>"]
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.
| 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.
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.