Transform Hierarchies
Summary
A transform hierarchy is a parent-child chain of positions, rotations, and scales, where each child's transform is expressed relative to its parent's, and moving a parent automatically carries every descendant along with it. A hand bone moving carries an attached weapon along with it, which carries an attached scope, without any of those objects needing to manually track the others' movement — the hierarchy does that automatically by construction.
Why This Matters
Objects in games are rarely independent — a weapon should move and rotate with the hand holding it, a turret's barrel should rotate independently of the tank body it's mounted on, a health bar should stay above a character's head as they move. Manually recalculating every attached object's world position and rotation every frame, in code, whenever a parent moves, is repetitive and error-prone. Transform hierarchies solve this structurally: define the relationship once (this is a child of that), and every subsequent parent movement automatically propagates to every descendant without additional code.
Mental Model
A transform hierarchy is a solar system's orbits, not independently floating planets. A moon orbits its planet, which orbits its star — moving the star (in some conceptual sense) carries the planet and moon along with it automatically, because the moon's motion is defined relative to the planet's, not as an independent absolute position. A weapon "orbiting" a hand bone, and a hand bone "orbiting" a character's body, works the same way: each level's motion is naturally inherited from the level above it.
Core Explanation
- A child's local transform is relative to its parent, not the world. The child's local position, rotation, and scale describe an offset from the parent's own transform — this is the same local-vs-world distinction covered in [[CON-0042]], applied specifically to a chain of parent-child relationships.
- A child's world transform is computed by combining every ancestor's transform. The engine combines the child's local transform with its parent's world transform (which is itself combined with its parent's, and so on up the chain) to determine where the child actually ends up in the world.
- Moving, rotating, or scaling a parent affects every descendant automatically. This propagation is the entire practical benefit of a hierarchy — it's what lets a single movement of a root object correctly carry an arbitrarily deep chain of attached children along with it.
- Scale compounds through the hierarchy, which can produce surprising
results. A child scaled
2xunder a parent already scaled2xends up4xin world scale — non-uniform or extreme parent scaling can distort children in ways that aren't obvious from the child's own local scale value alone.
Syntax / Theory
Engine-neutral (concept)
child.worldTransform = parent.worldTransform combined with child.localTransform
Moving parent.worldTransform automatically changes every descendant's
resulting worldTransform, without their localTransform values changing.
C# (Unity)
weaponTransform.SetParent(handBone); // Establishes the hierarchy relationship.
weaponTransform.localPosition = new Vector3(0.1f, 0f, 0.2f); // Offset relative to the hand.
// weaponTransform.position (world) now automatically follows handBone wherever it moves.
C++ (Unreal — Component attachment)
WeaponMesh->AttachToComponent(HandSocket, FAttachmentTransformRules::KeepRelativeTransform);
WeaponMesh->SetRelativeLocation(FVector(10.f, 0.f, 20.f)); // Local offset from HandSocket.
Unreal's component attachment system (often to a specific named "socket"
on a skeletal mesh) achieves the identical propagation behavior as
Unity's Transform parenting — a child's relative transform stays fixed
while its resulting world transform follows the parent automatically.
Practical Example
A simple two-level hierarchy — a turret base that rotates freely, and a barrel attached to it that only tilts up and down — demonstrates independent local rotation composing correctly into final world rotation.
public class Turret : MonoBehaviour
{
public Transform barrel; // Child of this turret's transform.
void Update()
{
transform.Rotate(Vector3.up, rotateSpeed * Time.deltaTime); // Turret yaws.
barrel.localRotation = Quaternion.Euler(currentPitch, 0, 0); // Barrel pitches, relative to turret.
}
}
The barrel's localRotation only ever needs to express "tilt up or down
relative to the turret" — its actual world-facing direction, correctly
combining the turret's yaw and the barrel's own pitch, is computed
automatically by the hierarchy.
Common Mistakes
- Setting a child's world position/rotation directly when a local value
was intended, or vice versa. Assigning
transform.positionon a deeply-nested child sets its absolute world position, which then gets silently re-expressed as whatever local value achieves that — subsequent parent movement can produce confusing results if the intent was actually to set a fixed local offset. - Not accounting for compounding scale. Nesting several scaled objects can produce a child far larger or smaller than its own local scale value suggests, since every ancestor's scale multiplies together.
- Building unnecessarily deep hierarchies "for organization" rather than for actual positional relationships. A hierarchy should reflect genuine "this moves with that" relationships — using parenting purely to group unrelated objects in an outliner panel couples their transforms together unintentionally.
- Forgetting that reparenting an object (changing which parent it's under) can change its resulting world position unless explicitly preserved. Moving a child to a new parent without accounting for the new parent's own transform can cause the child to visually "jump," since its local values are now interpreted relative to a different parent.
Game Development Example
A character's held item follows their hand precisely through an entire animated hierarchy — body, upper arm, forearm, hand, weapon — with each link only needing to know its relationship to the link directly above it.
public class HeldItem : MonoBehaviour
{
void EquipTo(Transform handBone)
{
transform.SetParent(handBone);
transform.localPosition = gripOffset;
transform.localRotation = gripRotation;
}
}
Once equipped, the weapon correctly follows every animated movement of the character's whole arm — shoulder rotation, elbow bend, wrist twist — with zero additional per-frame code, because each joint's animated local rotation composes automatically up through the hierarchy to the weapon at the end of the chain.
Best Practices
- Use parenting to reflect genuine positional relationships (this moves with that), not merely for scene-outliner organization.
- Prefer setting local position/rotation for attached objects whose offset from their parent should stay fixed, and world position/rotation only when an absolute placement is genuinely intended.
- Be mindful of compounding scale in deeply nested hierarchies, and prefer
keeping scale at
1on intermediate nodes where possible. - When reparenting, explicitly decide whether the object's world position should be preserved or its local values kept as-is, since most engines offer both options.
Exercises
- Build a two-level hierarchy (a parent cube and a child sphere offset from it), move and rotate the parent, and observe how the child's world position changes while its local position stays constant.
- Take the
Turretexample and add a third level — a muzzle point attached to the barrel — and confirm that a projectile spawned at the muzzle's world position correctly accounts for both the turret's yaw and the barrel's pitch without any extra code. - You're building a solar system simulation with a star, a planet orbiting it, and a moon orbiting the planet. Decide whether to implement each orbit via transform hierarchy parenting or via independent position calculations combined manually each frame, and justify the trade-off.
- Research the difference between "keep world transform" and "keep relative transform" options when reparenting an object in an engine, and explain a scenario where each option is the correct choice.
Related Concepts
- Coordinate Systems — a transform hierarchy is the mechanism that produces the local-vs-world distinction in practice, chaining that relationship across multiple levels.
- Game Objects — the parent-child relationships that make up a transform hierarchy are formed between game objects (or Actors/components), making this a direct extension of understanding what a game object is.
- Vectors — local position offsets within a hierarchy are themselves vectors, and combining a chain of transforms relies on the same vector and rotation math covered throughout this track.
Further Reading
KNOWLEDGE_SCHEMA.md— GDKB's concept maturity ladder and cross-linking rules, which this document follows.- Unity documentation — Transform, Parenting: https://docs.unity3d.com/Manual/class-Transform.html
- Unreal Engine documentation — Attachment and Component Hierarchies: https://dev.epicgames.com/documentation/en-us/unreal-engine/attachment-in-unreal-engine