Effect Zones & Conveyor Belts¶
Apply any process to every object inside a region, one independent run per object. A conveyor belt is just the flagship configuration.
Namespace: Jungle.Core (Detector) + Jungle.Spatial (Shape) + Octoputs.Transforming (Walk Along Shape)
How zones work¶
There is no dedicated "zone" component: a zone is a Detector doing what it always does. The detector's On Object Added process starts one run per object that enters, with that object as the run's context, and the run is completed the moment the object leaves. Wire any process into that slot and every object in the zone gets its own copy of the effect for exactly as long as it stays inside.
That means everything you already know about processes applies: transform pipelines, modifiers, signals, sequences. Nothing zone-specific to learn.
Grabbing and dropping need a container. A detector judges an object once, when it arrives, so cargo carried in by a claw is judged held and never reconsidered. For a zone whose members come and go with a state change rather than with movement, keep the members in a GameObjectListContainer and let a Reactor add and remove them, then run the effect on the container instead of on the detector. The shipped Factory Conveyor is built exactly this way and is the example to copy.
The belt is a shape¶
A conveyor belt is a Shape component holding a Line Shape, with Local Space turned on so the line moves with the belt and survives prefabbing. Select the belt's Path child to drag the line's start and end in the Scene view.
- Shape: Line Shape, from one end of the belt to the other.
- Local Space on, so the line moves with the belt.
Any shape works: a line, an arc, a circle, a 3D curve through Curve Shape, or a surface such as a plane, rectangle, disc or ring.
Walk Along Shape with Wait For Room¶
Walk Along Shape is the transform target that moves an object across a shape at a set speed. Route picks where it walks: straight along the shape's main direction (the default), straight across it, or a free route you draw on the shape. Turn on Wait For Room and the target also keeps every object it drives in a queue:
- Objects keep Spacing between each other and never overtake the one ahead.
- An object that starts where there is no room waits in place and joins as soon as a spot frees up.
- How many objects fit falls out of the spacing: an object joins wherever no other object is within one spacing of it, so a shape seats one more than its length divided by the spacing. To cap it lower than that, gate whatever puts objects on the belt.
- When a queued walk ends (the object leaves the zone or is grabbed), the object stays where it is instead of snapping to the end of the shape.
- An object belongs to one queue at a time. When the next belt in a line picks an object up, the belt it came from lets go at once and frees its spot, so cargo crosses from belt to belt at a steady speed instead of being pulled by both. The last belt of a line keeps its cargo queued until something takes it.
Because the queue lives on the authored target, one authored pipeline serves every object on the belt at once. Two pipelines pointing at the same shape do not share a queue.
When the shape itself moves¶
Speed is in world units per second, so the route has to be measured before anything can walk it. A line, arc, circle or curve walked along its main direction measures itself exactly and stays right whatever it does. Every other route is measured once when the walk starts, so if the shape moves, turns or resizes while objects are on it, turn on Shape Moves to re-measure each frame. Leave it off otherwise — it costs a measurement per frame. Accuracy sets how finely a drawn or across-the-shape route is measured; raise it if a curved route looks like it cuts corners.
| Property | Type | Description |
|---|---|---|
| structure | Shape |
The Shape component to walk along. |
| speed | SmartFloat |
Travel speed, in units per second. |
| loop | bool |
Go back to the start when the end is reached. |
| waitForRoom | bool |
Queue objects along the shape instead of letting them pass through each other. |
| spacing | SmartFloat |
Minimum distance between two queued objects, both to join and to follow. |
| rotationMode | ShapeRotationMode |
Preserve, align to the shape normal, align to the travel direction, or override. |
| completion | PipelineCompletionCheck |
For a belt, set to Never Stop: the ride ends when the object leaves the zone. |
Setting up a conveyor¶
Give each job its own child of the belt, the way the shipped Factory Conveyor does, so selecting a child shows one piece of the logic.
- Create a child named Zone with a trigger collider covering the belt volume, plus a Trigger 3D Relay on the same object.
- On Zone, add a
Detectorwith a Trigger & Collision strategy wired to the relay, and an Attachable Object Filter holding a Held / Free check (Free) as its selection. - Create a child named Cargo with a
GameObjectListContainer. This, not the detector, is the set of cargo currently riding. - Create a child named Path with a
Shapecomponent, pick Line Shape, turn on Local Space, and drag the line along the belt. - On Zone, add a
Reactorand give it a reaction watching the detector's Detected Attachable cycle. On begin, run a Container Command with a Store Value operation; on end, one with a Remove Value operation. Cargo now joins the set when a claw lets go of it inside the zone and leaves the set when a claw takes it, with nothing checked in between. - Create a child named Carry with a second
Reactor, and give it a reaction watching the container's Container Membership cycle. On begin, run a Process List with two entries: a Rigidbody Command (target: Context) running Set Kinematic (on), and a Transform Command (target: Context) holding a Set Transform over Time (Direct) operation. On end, mirror a Rigidbody Command with Set Kinematic (off) so physics resumes when cargo leaves. - Set the transform operation's destination to Walk Along Shape, point it at the Shape component, turn on Wait For Room, set the spacing to the size of your cargo, and set completion to Never Stop. Add a Smooth Position modifier for a soft catch-up onto the belt.
- Anything that enters the trigger now rides the belt, anything an agent grabs leaves it automatically, and anything an agent drops into the zone joins it.
Let the trigger volume cover the whole shape. A zone that stops short of the end of the line releases cargo before the line ends, and released cargo is no longer in the queue, so the next objects pile up on the same spot instead of backing up behind it. Covering the shape is what gives the belt real back-pressure.
Two details make this rock solid. The Direct operation drives kinematic rigidbodies through the physics engine (MovePosition), so the trigger overlap never flickers while cargo rides. And the detection strategy's Use Exit Grace absorbs the fake exit/enter pairs the physics engine fires when a body is rebuilt inside the volume (which is what toggling kinematic does). Turn it on for a zone that changes physics state on entry.
It buys that with staleness: for the length of the window, an object that really left is still listed as detected. A conveyor never notices, because nothing reads it on a deadline. A cursor or a hand does, because a click can land inside the window and pick up the thing the hand just moved off. Leave it off on anything a player reads directly.
Funnels, auto-arranging displays, repulsor fields: same recipe, different process in the On Object Added slot.