Skip to content

Events

Events connect moments - a button press, a timer, a collision - to actions. Wire any trigger to any behavior in the Inspector, and swap triggers without touching code.

The pattern is simple: something happens, and something responds. A mouse click starts a transfer. A timer fires and plays a sound. A collision triggers a visual effect. You pick the trigger and the response separately, so either one can change independently.


The Standard Trigger Pattern

The most common setup follows a three-part chain:

flowchart LR
    E["Trigger"] -->|fires| L["Launcher"]
    L -->|runs| P["Operation"]
  1. Trigger - Detects that something happened (input, timer, collision)
  2. Launcher - Listens for the trigger and starts an operation when it fires
  3. Operation - The process or command that executes in response

This decouples what triggers behavior from what the behavior does. You can swap the trigger (mouse click to touch input) or the operation (play animation to spawn particles) independently.


Built-in Event Types

Input Events

Event Trigger
InputButtonEvent Legacy Input Manager button press/release/hold
InputSystemActionEvent New Input System action performed
MouseButtonEvent Mouse button press/release/hold
RewiredButtonEvent Rewired input button (requires Rewired package)

Timing Events

Event Trigger
DurationEvent After a specified number of seconds
NextFrameEvent On the next frame after registration

UI Events

Event Trigger
ButtonClickEvent UI Button click
ToggleChangedEvent UI Toggle value changed
SliderChangedEvent UI Slider value changed

Scene Events

Event Trigger
GameObjectEvent GameObject lifecycle events (enable, disable, destroy)
PhysicsEvent Collision or trigger enter/exit/stay (from jungle.physics)
VideoStartedEvent Video player starts playback
VideoFinishedEvent Video player finishes playback

Asset Events

Event Trigger
EventFromAsset Delegates to a ScriptableObject-based event asset — useful for cross-scene or global events

Technical API

IEvent

The core interface for events:

public interface IEvent
{
    void Register(Action listener);
    void Unregister(Action listener);
    void Raise();
}
Method Purpose
Register(Action) Subscribe a callback that fires when the event is raised
Unregister(Action) Remove a previously registered callback
Raise() Fire the event, invoking all registered listeners

Events are serialized with [SerializeReference] and [JungleClassSelection], so the event source is fully configurable in the Inspector.


Event Listeners

The IEventListener interface wraps an event with additional control:

public interface IEventListener
{
    IEvent MonitoredEvent { get; }
    EventListeningStopCondition ListeningStopCondition { get; }
}

Event listeners add a stop condition to event subscriptions — for example, "listen for this event only once" or "stop listening when the GameObject is disabled." This prevents stale subscriptions and gives finer control over event lifetime.


Wiring Events in the Inspector

Events appear as TypeSelectableFields on launcher components. A typical setup looks like:

  1. Add a launcher component (e.g., ProcessLauncher) to a GameObject
  2. In the Event field, click the type selector and choose an event source (e.g., InputButtonEvent)
  3. Configure the event's properties (e.g., which button, press vs. release)
  4. In the Process field, choose the process to run when the event fires
  5. Configure the process

Testing events

Enter Play mode and trigger the event source. The launcher's process should start immediately. If nothing happens, check that the event type matches your input method and that the process is configured correctly.


Octoputs Event Usage

Octoputs defines its own event types for the transfer system:

Event Fires When
AttachableDetectorEvent An attachable object enters or exits a detector
AttachableStorageEvent An object is added to or removed from storage
AttachableObjectStatusEvent An attachable object changes status
AttachmentPointDetectorEvent An attachment point enters or exits a detector
AttachmentPointStorageEvent An attachment point is added to or removed from storage
AttachmentPointStatusEvent An attachment point changes status

These events allow you to trigger processes (visual feedback, sound effects, UI updates) in response to any step of the drag-and-drop lifecycle.


Practical Example

Goal: When the player presses a button, transfer an object from one storage to another.

InputButtonEvent ("Fire1", On Press)
    → ProcessLauncher
        → AttachableTransferProcess
            (source: InventoryStorage, destination: EquipSlot)

Setup:

  1. Create a GameObject with a ProcessLauncher component
  2. Set the Event field to InputButtonEvent, configure it for "Fire1" on press
  3. Set the Process field to AttachableTransferProcess, configure source and destination storages
  4. Press Play and hit the Fire1 button — the transfer executes

No code required. The entire chain is configured in the Inspector through Jungle's type selection system.


Creating Custom Events

Implement IEvent and add [JungleClassInfo]:

[Serializable]
[JungleClassInfo("Fires when a score threshold is reached", "Icons/score", "Gameplay")]
public class ScoreThresholdEvent : IEvent
{
    [SerializeField] private int threshold = 100;

    private Action listener;
    private bool fired;

    public void Register(Action callback)
    {
        listener += callback;
        fired = false;
    }

    public void Unregister(Action callback)
    {
        listener -= callback;
    }

    public void Raise()
    {
        if (!fired)
        {
            fired = true;
            listener?.Invoke();
        }
    }

    // Call this from your score system when the score changes
    public void CheckScore(int currentScore)
    {
        if (currentScore >= threshold)
            Raise();
    }
}

Event vs. polling

Events are reactive — they fire when something happens. If you need to check a condition every frame, use a FlexibleProcess with an execution condition instead. Events are best for discrete moments: a click, a collision, a threshold crossing.