Tutorial: Transform Operations¶
Control how objects move — add bounce, snap to a grid, avoid walls, or make objects feel heavy. Instead of teleporting from A to B, you'll make objects move with personality.
By the end you'll have a cube that springs toward its slot with overshoot, stays locked to a horizontal plane, and slides around obstacles instead of clipping through them.
Prerequisites: Complete Your First Drag and Drop. You should have a Cube + DestinationPoint with a working attach.
How Movement Works in Octoputs¶
Every time an object attaches to a slot, something moves it into position. That something is a transform operation — an IProcess with three internal stages:
- Target — where should it go?
- Modifiers — what should adjust the path on the way?
- Applier — how should the final position be written? (Direct transform write, physics force, joint constraint, …)
flowchart LR
T["Target<br/>(destination)"] --> M1["Modifier 1"] --> M2["Modifier 2"] --> M3["..."] --> A["Applier"]
Each piece is independent and swappable.
Operations on an AttachmentPoint vs a Transformer¶
You can author transform operations in two places:
- Inline on an AttachmentPoint — drop them into its Attaching / Detaching processes. This is what new AttachmentPoints do out of the box: their default attaching process contains a
DirectTransformOperationon the held object. - In a Transformer, when the move is its own concern or several objects move together.
This tutorial works on the AttachmentPoint's attaching process. The same operations apply to the Transformer.
0. The Fast Way: Pick a Preset¶
Before building anything by hand, try a preset. Every transform operation field has a small preset button at the right of its header. Click it and you get a list of ready-made feels, each with a line saying how it moves:
- Drag: Smooth, Snappy, Polished, Heavy, Jelly, Tilt, Surface Glide, Grid, Leash, Levitate, Ice, Wall-Safe, Pendulum.
- Drag (Physics): Polished and Heavy. These need a Rigidbody on the object.
- Attach: Smooth, Snap, Pop, Magnet. Use these on an attachment point to change how things land.
Picking a preset changes how the object moves, never where it goes: the destination and the point you hold it by stay as you set them. Found a setup you like? Click Save Current as New Preset... at the bottom of the list and it shows up in every matching field.
The rest of this tutorial builds these feels by hand, so you can tune them or make your own.
1. Look at the Default Operation¶
Select DestinationPoint in the Hierarchy. In its AttachmentPoint inspector, open the Attaching tab. You'll see a process that contains, among other things, a Set Transform over Time (Direct) operation with the default pivot (AttachablePreferredTransformPivot).
That's the snap-to-position behaviour. We'll customize it.
Why an Operation and not a separate component?
Transform operations are IProcess items hosted inside command lists. They begin when their host begins, end when their host ends, and can be composed (Sequence, Parallel) like any other process. That's the same composition pattern used everywhere in Jungle, so anything you learn here applies to operation lists in commands, reactor bodies, agent preparation processes, and so on.
2. Set the Destination¶
The target answers the question where should the object end up?
The default DirectTransformOperation on AttachmentPoint comes with a target that already resolves to this point. If you want to override:
- In the operation, find the Target field.
- Click the type selector. The current type is
Follow Target(or similar — concrete name shown in the picker). - To redirect the destination, pick
Follow Targetand drag any Transform reference into it.
Other target types
Octoputs ships targets for many shapes of "where to go":
RayHitTransformTarget— follow a raycast hit point on a surface.LerpedTransformTarget— lerp from current to a destination over a duration.ShapeTraversalTransformTarget— travel a route across any shape at a set speed.BlendedTransformTarget— interpolate between two targets using a weight.SequenceTransformTarget— step through a list of targets in order.CompositeTransformTarget— take position, rotation and scale each from its own target.RestPoseTransformTarget: stay where it started inside its parent; add Momentum, Tilt By Velocity or Spring and a child lags, tilts and wobbles as its parent moves.
See the API Reference for the full list.
Choose what gets copied¶
Every transform operation has Position, Rotation and Scale under its Options, whatever target it uses.
- World puts the object at the target's spot, or turns it the way the target faces, in the scene.
- Local gives the object the same offset inside its own parent as the target has inside its parent. A target that has no parent, such as a ray hit, gives its numbers as that offset.
- Off leaves that part alone, so the object keeps its own turn or size while it moves. Scale is Off by default.
Use Rotation Off for a slot that should keep the object's turn, and Scale World for a slot that should make the object the size of the slot whatever its parents are scaled by.
3. Add Bounce with a Spring Modifier¶
Modifiers sit between the target and the applier, adjusting the computed position before it's written. Let's make the cube overshoot its target and spring back.
- Find the Modifiers list inside the transform operation.
- Click + to add an entry.
- From the type selector, choose Spring (under the Physics category).
| Field | Tuning hint |
|---|---|
| Spring Strength | 1200 is snappy; 300 feels lazy. |
| Damping | 20 settles fast; 8 lets it bounce. |
| Max Spring Range | Clamps how far the spring will stretch. |
| Max Velocity / Acceleration | Caps for stability. |
| Wobble Amount | 1 is a full swing; 0.3 stays close to the cursor and keeps the bounce. |
| Max Movement Per Axis | Furthest it swings along each of the object's own axes. 0 locks an axis; (Infinity, 0, Infinity) swings sideways but never bobs up or down. |
Try Spring Strength = 300, Damping = 8 for a visible overshoot. Increase Damping to kill bounce, or raise Spring Strength for a snappier feel.
Rule of thumb
Strength ≈ 10× Damping → visible bounce. Strength ≈ 60× Damping → tight follow, almost no overshoot.
Press Play and re-attach. The cube now springs into the slot.
4. Lock an Axis¶
Modifiers execute top to bottom. Each receives the previous one's output. You can stack as many as you want.
Add a second modifier:
- + in the Modifiers list.
- Pick Position Constraint (under Constraints) and set its constraint to Keep On Shape with a Plane Shape (Right X, Up Z).
- Turn on Relative To Drag Start, so the plane sits at the height the cube was picked up at.
The chain is now:
flowchart LR
T["TransformTarget"] --> S["SpringModifier"] --> A["PositionConstraintModifier"] --> P["Applier (Direct)"]
Play. The cube springs in X and Z, but Y is locked.
Order matters
Swap the order — the constraint first, then Spring — and the spring reintroduces Y motion after the lock. Always place constraints after dynamic modifiers when the constraint should have the final word.
5. Use Physics Instead of Direct Writes¶
So far the operation writes the transform directly each frame. For objects that need to push other things, respect gravity, or settle against world geometry, swap the operation type itself — not just a modifier.
- Select DestinationPoint again and open the Attaching tab.
- In its process, replace the
DirectTransformOperationwith a Physics Transform Operation. - Configure the target the same way as before.
Rigidbody required
The cube needs a Rigidbody. If it doesn't have one, add it now (Add Component → Physics → Rigidbody).
Key fields on PhysicsTransformOperation:
| Setting | What it does |
|---|---|
| Use Velocity Based | On: assigns linearVelocity directly. Off: applies forces. |
| Spring Strength / Damper | Velocity-mode pull. |
| Movement Force | Force-mode pull. |
| Max Velocity | Cap to prevent runaway. |
| Override Gravity | Disable gravity while running. |
| Freeze Rotation | Lock rotation during movement. |
Use Direct when placement should be pixel-perfect (UI, strategy, editors). Use Physics when the object lives in a physical world and must push, collide, and interact (VR, physics puzzles).
6. Slide Around Obstacles¶
Physics operations get collision response from the Rigidbody. Direct operations don't — they teleport through geometry. To prevent clipping with a direct operation, add a collision modifier.
Switch the operation back to DirectTransformOperation for this step. Add one of:
| Modifier | How it works | Best for |
|---|---|---|
| Depenetration | Uses Physics.ComputePenetration to push out of overlaps. |
General-purpose, physically correct push directions. |
| Surface Slide | Sweeps the bounding box, slides along surfaces on contact. | Smooth surface-following while dragging. |
For this tutorial, pick Surface Slide.
Drop a wall or two between the cube's start position and DestinationPoint. Re-trigger the attach. The cube glides around the wall instead of clipping through it.
Layer mask
Both collision modifiers expose a Layer Mask field. Default is "everything". Restricting to obstacle layers improves performance and avoids accidental self-collisions.
7. Composing Operations: Sequence and Parallel¶
So far we've stacked modifiers inside a single operation. Sometimes you want to stack operations themselves — e.g. "scale up, then move, then scale back".
That's what SequenceTransformOperation and ParallelTransformOperation are for. They're transform operations whose body is a list of child transform operations on the same subject.
To run them, use a Transformer (or replace your AttachmentPoint's attaching process with a sequence):
- Select the object and use Add Component → Jungle → Spatial → Transformer.
- Set its first motion's Movement to a Sequence Transform Operation.
- Add child operations: scale up, then translate, then scale back.
When the component starts, the Sequence runs its children in order. To move several objects at once, see Transformer.
8. Big Crowds: the Batch Pipeline¶
When you have hundreds of attachables doing the same kind of motion, regular transform operations one-by-one stop being fast enough. Octoputs ships a Burst/Jobs-based batch pipeline as a drop-in.
- Add a BatchTransformPipelineManager somewhere in the scene.
- On each AttachmentPoint that needs batch handling, replace its inline transform operation with a
BatchTransformOperationthat submits the subject to the manager. - Configure the batch modifiers in the manager (Smooth Position, Snap2DGrid, Spring, Oscillator, KinematicsLimiter, AntiJitter, Pivot — the same primitives, Burst-friendly).
The trade-off: batch modifiers are a focused subset of the full modifier catalog. Use it where throughput matters; stay with the regular operations elsewhere.
See BatchTransformPipelineManager.
Modifier Reference¶
Octoputs ships 30+ modifiers across categories. Quick reference — see API Reference for full details.
Constraint and snapping¶
| Modifier | What it does |
|---|---|
PositionConstraintModifier |
Keep the position on a plane, rail, volume or grid; optionally relative to the pick-up point. |
RotationConstraintModifier |
Lock axes, limit angles or snap rotation; optionally relative to the pick-up rotation. |
OrbitConstraintModifier |
Constrain to an orbital path. |
HeightLockModifier |
Follow the height of the ground below. |
Physics and dynamics¶
| Modifier | What it does |
|---|---|
SpringModifier |
Elastic, bouncy motion. |
ElasticBandModifier |
Rubber-band pull-back beyond a threshold. |
MomentumModifier |
Carry inertia after release. |
KinematicsLimiterModifier |
Cap velocity / acceleration. |
Raycast and collision¶
| Modifier | What it does |
|---|---|
DepenetrationModifier |
Push out of overlaps. |
SurfaceSlideModifier |
Sweep + slide along surfaces. |
OBBCollisionAvoidanceModifier |
OBB-based avoidance. |
CameraRaycast2DOffsetModifier |
Offset from a 2D camera raycast. |
OcclusionRayPushModifier |
Cast a ray from the camera to the upstream wanted point; when the path is occluded, push onto the impact surface with a configurable offset. No-op when clear. |
BoundingOffsetFromHitNormalModifier |
Offset from surface using hit normal + object bounds. |
Alignment and orientation¶
| Modifier | What it does |
|---|---|
SurfaceNormalAlignmentModifier |
Align rotation to a surface normal. |
GravityAlignmentModifier |
Align rotation to gravity. |
TiltByVelocityModifier |
Tilt in the direction of motion. |
LookAtModifier |
Face a target point or direction. |
Animation and oscillation¶
| Modifier | What it does |
|---|---|
OscillatorTransformTargetModifier |
Bob / sway / breathe while held (position, rotation, scale). |
SquashStretchModifier |
Volume-preserving squash and stretch in response to scale or speed. |
NoiseOffsetModifier |
Perlin noise wiggle. |
PendulumSwingModifier |
Pendulum swing on pickup. |
Smoothing and filtering¶
| Modifier | What it does |
|---|---|
SmoothPositionModifier / SmoothRotationModifier |
Damped follow. |
AntiJitterModifier |
Suppress micro-jitter. |
Specialized¶
| Modifier | What it does |
|---|---|
PreserveViewRelativeOrientationModifier |
Keep visual angle to camera through perspective. |
InfluenceModifier |
Pull the target toward an influence pose (e.g. a barycenter of Points of Interest). Activation is automatic — fades in while the influence source has a pose, out when it doesn't. |
RepelModifier |
Push the target out of a bubble around one or more source objects, like a ship's force field. Strength 1 keeps it out entirely; the Falloff curve softens the push toward the edge. |
ScaleByDistanceModifier |
Scale by distance from a reference. |
ConditionalModifier |
Apply a wrapped modifier only when a Condition is true. |
Modifier Blend Factor¶
Every modifier carries a Blend Factor (default 1) — a SmartFloat that lerps between pre-modifier and post-modifier values each frame. 1 = full effect, 0 = passthrough, anywhere between = a partial blend. Wire it to any value source (data storage, slider, observable) to fade modifier effects in and out at runtime.
Next Steps¶
- Restrict which objects accept which slots with Tag-Based Filtering.
- Drive a full robot arm or NPC carrier with AttachingAgent Workflow.
- Add hard spatial limits with a Constrainer.
- Browse every component in the API Reference.