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"]
- Trigger - Detects that something happened (input, timer, collision)
- Launcher - Listens for the trigger and starts an operation when it fires
- 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:
- Add a launcher component (e.g., ProcessLauncher) to a GameObject
- In the Event field, click the type selector and choose an event source (e.g., InputButtonEvent)
- Configure the event's properties (e.g., which button, press vs. release)
- In the Process field, choose the process to run when the event fires
- 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:
- Create a GameObject with a
ProcessLaunchercomponent - Set the Event field to
InputButtonEvent, configure it for "Fire1" on press - Set the Process field to
AttachableTransferProcess, configure source and destination storages - 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.