Joint Chains (IK)¶
Make a jointed chain — like a robotic arm — bend so its tip reaches the drag target.
Namespace: Octoputs.Transforming.IK
Overview¶
Most transform appliers move one object to the target (Direct, Physics, Joint). The IK applier instead drives a chain of joints so the grabbed tip reaches the target — a robotic arm, a crane, a desk lamp, a tentacle.
It slots into the normal transform pipeline as just another applier:
flowchart LR
T["Target<br/>(destination)"] --> M["Modifiers<br/>(spring, snap, …)"] --> A["Reach Target with<br/>Joint Chain (IK)"]
Because it sits where Direct/Physics/Joint sit, every target and modifier you already use works unchanged — spring-smoothed reach, snap-to-grid targets, blend factors, completion checks.
It is purely kinematic: it only rotates bones that already exist in your scene. No Rigidbody, no physics, nothing spawned at runtime. The grabbed object is the tip of the arm; the joints are its ancestors in the hierarchy.
Setting up an arm¶
- Build the arm as a normal Transform hierarchy:
Base → Shoulder → Elbow → Wrist → Gripper. Each link is a child of the previous one. - Put an AttachableObject (or whatever you grab) on the Gripper — the tip.
- On the operation that drives the gripper (e.g. an AttachmentPoint's Attaching process, or a Transformer's motion), choose Reach Target with Joint Chain (IK) as the operation.
- Under Chain Setup, drop
Shoulderinto Chain Root andGripperinto Chain Tip, then press Build Chain. The joints list fills itself withShoulder,Elbow,Wrist, base first. (The gripper is the tip and is never listed — it is the dragged object.) - Press Suggest Hinge Axes and check the result in the Scene view, then give the joints that need one a Hinge Angle Limit.
- Chain Root and Chain Tip name the two ends of the arm.
- Build Chain fills the Joints list for you.
- One joint per bone, each with a hinge axis and an optional limit.
Chain Setup¶
The block at the top of the applier (IKChainSetup). It names the two ends of the arm so the editor can do the authoring for you. Neither field drives the solve — at runtime the tip is whatever the run is moving; these are the reference the tooling measures against.
| Field | Type | Description |
|---|---|---|
| chainRoot | Transform |
The topmost joint that may rotate. Everything from here down to the tip becomes a joint. Leave empty to use every ancestor of the tip. |
| chainTip | Transform |
The end of the arm — the object that gets grabbed. Not a joint itself. |
| Button | What it does |
|---|---|
| Build Chain | Replaces the joints list with one joint per bone from root to tip, base first. Joints already authored for a bone keep their hinge axis and limit, so rebuilding after re-parenting a link is safe. |
| Add Selected | Appends a joint for every Transform selected in the Hierarchy that is not in the list yet. Use it for arms you want to author a piece at a time. |
| Suggest Hinge Axes | Guesses a hinge axis for every joint still on Free, from the direction of the next bone. A guess — the Scene view gizmos are how you check it. |
Below the buttons the block reports anything wrong with the chain — an empty bone slot, a bone listed twice, the tip listed as a joint, a bone that is not above the tip in the hierarchy, joints out of base → tip order — each with the button that fixes it.
Seeing the chain¶
Select the object holding the applier and the chain is drawn in the Scene view, in Edit mode as well as Play mode:
- Blue run of segments — the chain from base to tip. A segment turns red when the next joint is not actually a child of it, which is what an out-of-order list looks like.
- Gold line through a joint — its hinge axis. A joint with no hinge axis gets a small sphere instead, to read as "turns any way".
- Green wedge — the angles a limited joint may turn through, measured from its rest pose, with an orange line showing where the joint is now.
- Faint sphere at the base — how far the tip can get with the chain laid out straight.
Reach Target with Joint Chain (IK)¶
The applier (IKChainTransformOperation).
| Field | Type | Description |
|---|---|---|
| setup | IKChainSetup |
The two ends of the arm, used by the editor to build and check the chain. See Chain Setup. |
| bonesAboveTip | int |
0 bends the joints list. Above 0, each run bends that many bones above the object it moves instead, as free joints, and the joints list is hidden. One operation can then drive many chains: point its Transform Command at every tip, like all the tentacle tips of a creature. Pair it with Hold Rest Pose set to Measured In the creature's body so each tip reaches for its own rest spot. Default 0. |
| joints | IIKJoint[] |
The chain's joints, base (root) first, tip last. The grabbed object is the tip and is not in this list. |
| solver | IIKSolver |
How the chain bends. Default: Cyclic Coordinate Descent. |
| iterations | SmartInt |
Maximum refinement sweeps per frame. More = straighter reach, slightly more cost. Default 10. |
| positionTolerance | SmartFloat |
Stop refining once the tip is within this distance (metres) of the target. Default 0.001. When a frame's step is shorter than the tolerance (very high frame rates or slow-moving targets), the solver uses a tighter threshold so the arm keeps moving. |
| bendToward | SmartVector3 |
A point the middle of the chain bends toward, like the elbow of an arm. The tip still goes to the target; this only picks which way the joints fold to get there. Read it from an object's position to steer the bend while the game runs. Default zero (no bend preference). |
| bendStrength | SmartFloat |
How hard the chain is pulled toward Bend Toward, from 0 to 1. 0 ignores it. 1 swings the joints fully to that side every frame; lower values drift there over a few frames. Default 0. |
When the target is out of reach, the tip simply stops as far along as the chain allows — it is never teleported — so the pipeline keeps trying until the target comes back into range.
Bone Joint¶
Each entry in the Joints list (HierarchyIKJoint).
| Field | Type | Description |
|---|---|---|
| bone | Transform |
The bone this joint rotates. Must be an ancestor of the grabbed tip. |
| hingeAxis | IKHingeAxis |
Which of the bone's local axes the joint turns about: Free (a ball-like joint), X, Y, Z, or Custom. |
| hingeAxisLocal | Vector3 |
The axis as a raw vector, shown only when hingeAxis is Custom. |
| limit | IRotationConstraint |
Optional movement limit. Empty = no limit. Hinge Angle Limit is the one built for joints; any Octoputs rotation constraint also works. |
Joint limits are not a new system — they are the same rotation constraints used by the Constrainer.
Hinge Angle Limit¶
The limit built for joints (HingeAngleLimit). Two numbers: the lowest and highest angle the joint may turn to, in degrees.
| Field | Type | Description |
|---|---|---|
| minAngle | SmartFloat |
Lowest angle from the rest pose. Negative turns the other way. |
| maxAngle | SmartFloat |
Highest angle from the rest pose. |
| fallbackAxis / fallbackReference | — | Only used when the limit is not on an IK joint (on a Constrainer, say). A joint supplies both itself. |
Zero is the bone's rest pose — the local rotation it has in the scene when the chain first initializes. That is what makes the limit two numbers instead of a reference quaternion you have to work out: an elbow that only bends one way is min 0, max 150, authored against the arm as you posed it.
The limit is a true hinge: the rotation is reduced to a twist about the axis, so off-axis swing is dropped rather than clamped. That means it enforces the hinge even on a joint left at Free.
Pose the arm before you press Play
The rest pose is captured once, from the pose the bone is in at chain start. Author the arm in its neutral pose and the angles mean what they look like.
Cyclic Coordinate Descent¶
The default solver (CcdSolver). Each sweep walks the chain from the joint nearest the tip back to the base, rotating every joint so the tip aims at the target, then clamping that joint to its limit. Robust, allocation-free, and naturally honours per-joint angle limits and hinge axes.
Raise iterations for a straighter, snappier reach on long chains; lower it for a lazier, trailing follow.
| Field | Type | Description |
|---|---|---|
| spread | float (0 – 0.95) |
How evenly the bend spreads along the chain. 0 lets each joint turn all the way at once, so the joints near the tip do most of the bending. Higher values make every joint take a smaller share, so the whole chain curves like a tentacle; give it more iterations to reach the target. |
| matchRotation | bool |
Also turn the tip the way the target is turned. The last joint becomes a wrist: it takes the turn, and the joints before it bring the wrist to where the tip lands right. A target you rotate then sets the angle of a fingertip or a gripper. Off (default): only the target's position counts. |
Follow-ups¶
- Physical arms — feed the solved joint angles to articulation/joint drives so the arm can push and be pushed (today the arm is kinematic and passes through obstacles).
- Separate target marker — reach toward an object the arm is not attached to (today you grab the tip itself).