Skip to content

Objects

Reference, find, and manage GameObjects and Components as configurable values - enable, disable, instantiate, and pool objects.

Jungle.Objects gives you Inspector-configurable operations for scene objects and UI elements. You can activate or deactivate GameObjects, reparent them, set positions, change layers, control CanvasGroup properties, transfer objects between storages, and manage object pools - all without writing custom scripts. The package builds on the value provider and process systems, so every object reference is swappable from the Inspector.

Assembly: Jungle.Objects (depends on Jungle.Core)

Namespace: Jungle.Objects


GameObject Value Providers

Value providers give you a flexible way to reference GameObjects. Instead of hard-wiring a reference, you pick a source strategy from the Inspector - a direct reference, a shared ScriptableObject asset, the first object in a storage, the last detected object, and so on. The consuming code stays the same regardless of where the reference comes from.

All value providers implement IGameObjectValue (which extends IValue<GameObject>). Use them anywhere a process, command, or modifier needs a GameObject reference.

Provider Category Description
GameObject Value (default) Direct serialized reference to a GameObject.
GameObject Array Value (default) Serialized array of GameObjects. Supports multi-value access.
GameObject Value From Asset Lookup Reads from a shared GameObjectValueAsset ScriptableObject.
GameObject List From Asset Lookup Reads from a shared GameObjectListValueAsset ScriptableObject.
Value From Reference Lookup Reads from a GameObjectValueReference component in the scene.
From Storage Storage Picks a GameObject from a GameObjectStorage (first, last, or random).
First In Storage Storage Returns the first available object in a storage.
Last In Storage Storage Returns the last available object in a storage.
All In Storage Storage Returns all objects in a storage as a multi-value provider.
All Detected Detector All GameObjects currently seen by a DetectorBase.
Last Detected Detector The most recently detected GameObject.
Last Removed From Detector Detector The most recently lost/removed GameObject.

Usage

Declare a value provider field on any serialized class:

[SerializeReference] [JungleClassSelection]
private IGameObjectValue target = new GameObjectValue();

Then resolve it at runtime:

GameObject go = target.V; // shorthand for target.Value()
if (!go) return;
// use go...

The user picks the concrete source in the Inspector through the class selection system. The code never changes.

GameObjectValueReference

A MonoBehaviour that holds a settable ISettableGameObjectValue and fires targeted commands when the value changes. Use it as a reactive binding point in the scene:

// Other code can write to it
reference.SetValue(someGameObject);
// Configured on-change commands automatically fire with the new object as target

// Clear it
reference.Clear();

Storage Value Providers

Storage references also use the value system. IGameObjectStorageValue extends IValue<GameObjectStorage>.

Provider Description
Storage Value Direct reference to a GameObjectStorage component.
Storage Value Asset Reads from a shared GameObjectStorageValueAsset ScriptableObject.
Storage From Asset Alias for reading a storage reference from a ScriptableObject asset.

CanvasGroup Value

For UI workflows, ICanvasGroupValue provides a CanvasGroup reference the same way IGameObjectValue provides GameObjects:

[SerializeReference] [JungleClassSelection]
private ICanvasGroupValue target = new CanvasGroupValue();

Commands

GameObjectCommand

A modular command that runs a configurable list of IGameObjectAction operations on a single target. Instead of creating separate components for each operation, compose them in one command.

[Serializable]
public class GameObjectCommand : TargetedCommand
{
    [TargetField]
    [SerializeReference] [JungleClassSelection]
    private IGameObjectValue target = new GameObjectValue();

    [SerializeReference]
    [JungleClassSelection(typeof(IGameObjectAction), ToggleSet = true)]
    private List<IGameObjectAction> actions = new();
}

Available Actions

Action Description
Activate Enable, disable, or toggle the GameObject's active state.
Set Parent Reparent under a new transform (world position preserved by default).
Set Position Set world or local position. Uses SmartVector3 for dynamic sources.
Set Rotation Set world or local rotation via Euler angles.
Set Scale Set local scale.
Set Layer Change the physics/rendering layer. Optionally recursive to children.
Set Tag Change the GameObject's tag at runtime.

Each action implements IGameObjectAction:

public interface IGameObjectAction
{
    void Execute(GameObject target);
}

UICommand

The UI equivalent of GameObjectCommand. Runs a list of IUIAction operations on a single CanvasGroup.

[Serializable]
public class UICommand : TargetedCommand
{
    [TargetField]
    [SerializeReference] [JungleClassSelection]
    private ICanvasGroupValue target = new CanvasGroupValue();

    [SerializeReference]
    [JungleClassSelection(typeof(IUIAction), ToggleSet = true)]
    private List<IUIAction> actions = new();
}

Available UI Actions

Action Description
Set Alpha Sets canvasGroup.alpha through a float pipeline (supports modifiers like clamp, remap, ease).
Set Blocks Raycasts Enable, disable, or toggle blocksRaycasts.
Set Interactable Enable, disable, or toggle interactable.

Storage

GameObjectStorage

The abstract base class for all storages that hold GameObjects. Concrete implementations are assigned in the Inspector. Any process or command that takes a GameObjectStorage field works with any implementation.

Key API:

public abstract class GameObjectStorage : ItemStorage<GameObject>
{
    IEnumerable<GameObject> Available { get; }
    int Count { get; }
    int Capacity { get; }

    GameObject TryTake();
    bool TryReturn(GameObject item);
    bool TryRemove(GameObject item);
    bool CanAccept(GameObject item);
    void Take(Action<GameObject> onReady);
    void Store(GameObject item, Action<bool> onComplete);
}

GameObjectListStorage

A simple list-backed storage. Items can be pre-assigned in the Inspector or added/removed at runtime.

  • Component menu: Jungle > Storage > GameObject List Storage
  • Configurable capacity (-1 for unlimited)
  • LIFO ordering: TryTake() removes the last item

Storage Transfer

Two ways to move objects between storages:

Type Description
StorageTransferCommand Fire-and-forget. Takes from source, stores in destination, completes immediately. If the destination rejects the item, it is returned to the source.
StorageTransferProcess Same logic but implements IProcess - completes only after the full take-then-store chain finishes.
// Both use the same field pattern:
[SerializeReference] [JungleClassSelection]
private IGameObjectStorageValue source;

[SerializeReference] [JungleClassSelection]
private IGameObjectStorageValue destination;

Object Pooling

The pooling system is built on top of GameObjectStorage, so pools integrate seamlessly with storage-based commands and value providers.

PoolStorage

A GameObjectStorage that manages a pool of prefab instances.

  • Component menu: Jungle > Storage > Pool Storage
  • Pre-instantiates a configurable number of objects on Awake
  • Grows on demand up to an optional maxCount
  • Enforces a maxActive limit (oldest acquired object is force-returned when exceeded)
PoolStorage
  Prefab:         Bullet          (must have PoolObject component)
  Initial Count:  10
  Max Count:      50              (0 = unlimited)
  Pool Parent:    (this transform)
  Max Active:     0               (0 = unlimited)

PoolObject

Attach to the pooled prefab. Manages the acquire/release lifecycle:

  • Acquire: activates the GameObject, arms the return trigger, fires OnAcquired
  • Release: disarms the trigger, runs the back-to-pool process, deactivates, fires OnReleased

Optional configurable fields:

Field Description
Return Trigger IPoolReturnTrigger - determines when the object auto-returns.
Out Of Pool Process IProcess to run when the object is acquired (e.g., a spawn animation).
Back To Pool Process IProcess to run when the object is released (e.g., a fade-out).

Return Triggers

Trigger Description
On Disable Returns to pool when the GameObject is disabled externally.
Timer Returns to pool after a configurable delay (seconds).

Implement IPoolReturnTrigger for custom return logic:

public interface IPoolReturnTrigger
{
    void Arm(PoolObject poolObject);   // Start monitoring
    void Disarm();                      // Stop monitoring
}

Pool Workflow

flowchart LR
    subgraph PoolStorage
        I[Inactive List]
    end
    subgraph Scene
        A[Active Objects]
    end
    I -->|TryTake / Acquire| A
    A -->|Release / Return Trigger| I
  1. PoolStorage.TryTake() removes an object from the inactive list and adds it to active
  2. PoolObject.Acquire() activates the GameObject and arms the return trigger
  3. When the trigger fires (or Release() is called), the object deactivates and returns to the inactive list
  4. The optional out-of-pool and back-to-pool processes run during acquire/release transitions

TargetedProcess

Resolves a target from an IGameObjectValue, injects it into all inner ITargetedProcess and ITargetedCommand children, then runs them. Use for orchestrating multiple operations on a dynamically resolved object.

// Configured in Inspector:
// Target:              IGameObjectValue (resolved at runtime)
// On Begin Commands:   List<ITargetedCommand>
// Processes:           List<ITargetedProcess>
// On Complete Commands: List<ITargetedCommand>

The target GameObject is set as OverrideTarget on each command and process before execution. Completion fires after all inner processes finish.


Utility Extensions

The package includes convenience extension methods in the Jungle namespace:

MonoBehaviourExt

// Delayed execution (uses UpdateManager, no coroutine needed)
this.StartDelayed(0.5f, () => DoSomething());

ObjectExt

// Repeat an action N times
5.Times(() => SpawnEnemy());
5.Times(i => SpawnEnemy(i));

// Activation shortcuts
gameObject.SetActive();    // SetActive(true)
gameObject.SetInactive();  // SetActive(false)

// Create child/sibling GameObjects
var child = gameObject.CreateNewChildGameObject("Child");
var sibling = gameObject.CreateNewSiblingGameObject("Sibling");