Parenting Game Objects For Clean Transformations
Grouping GameObjects for Organized Hierarchies
Establishing parent-child relationships between GameObjects in Unity builds clean transform hierarchies. The paradigm allows developers to move, rotate, and scale GameObject groups efficiently through manipulating parent transforms. However, improper parenting can propagate unchecked transformations down the hierarchy.
Using the built-in GetChild() method returns subordinate GameObjects for easy reference. Parents should containerize direct children only, preventing distant descendants from inheriting unintended changes. Object graphs with shallow trees minimize contamination across generations.
Benefits of parenting GameObjects
Parenting condenses scenes into logical units. Transforming root parents applies transformations uniformly to all children. Code referencing parent GameObjects indirectly modifies entire sub-hierarchies. This simplifies coordinate manipulations across grouped content prefabs. Shallow parent-child object graphs maximize organization with limited propagation.
Setting up parent-child relationships
Parent-child relationships build clean hierarchies. Drag-and-drop parenting in the Inspector defines logical organization. Programmatically, the SetParent() function parents GameObjects. Parent references must set before adjusting child transform properties. SetParent() also parents new GameObject instantiations before manipulation. Again, shallow trees minimize downstream mutations.
Referencing transforms with GetChild()
GetChild() grabs direct descendant GameObjects from parents. Storing GetChild() references simplifies manipulating immediate children. For example, GetChild(0).transform.position teleports the first child to a new coordinate. GetChild() only applies to the current generation; distant descendants need separate handling. Shallow hierarchies reuse GetChild() without inheritance issues.
Cleaning Up Inherited Transformations
Transform adjustments on parent GameObjects accumulate on children. For example, a rotated parent skew child orientations unpredictably. GameObjects later detached carry inherited transformations. Special handling prevents unintended mutations when parenting, unparenting, disabling, and enabling GameObjects.
Understanding transform accumulation
Parent GameObject transformations propagate to children. Rotation accumulates quaternion values multiplicatively down hierarchies. Position and scale compound additively. Accumulated mutations persist detached from parents. Clean households zero transformations on children before adjustments to avoid contamination.
Zeroing out rotation and scale on start
The Start() lifecycle event initializes GameObjects before scene launches. Here ResetTransformation() clears rotation and scale differentials cascaded from removed parents. New parents apply intended mutations relative to identity. Examples below demonstrate ResetTransformation() implementing Vector3.zero, Quaternion.identity, Vector3.one parameterization.
Resetting transforms with SetParent()
SetParent() simultaneously parents GameObjects and resets transformations. The optional worldPositionStays argument preserves positions while zeroing rotation and scale. This cleanly detaches GameObjects from old parents before assigning new parents. Otherwise, positional discontinuities manifest teleporting between coordinate spaces.
Simplifying Coordinate Manipulations
Unity transforms use either world space or local space. Parent space maps locally onto parents. Manipulations in inconsistent coordinate spaces cause jarring visual glitches. Special helper methods transition spaces cleanly. Also, leveraging parent transforms eliminates manually adjusting each child.
Changing local vs world space
Convert coordinate space with TransformPoint(), InverseTransformPoint() and TransformVector(). TransformPoint() converts local positions to world points. InverseTransformPoint() goes vice versa. TransformVector() handles directions. Parenting examples below demonstrate proper coordinate space transformations.
Teleporting child objects
Parenting teleports child objects when spaces mismatch. Detach children before moving parents to avoid jumps. Or, move parents first then reattach stationary children. Additionally, zeroing child transforms eliminates accumulated deltas. Clean parent transforms prevent erratic behavior.
Example code for moving children
Here is sample code for smoothly moving child objects:
parentTransform.DetachChildren(); ResetChildrensTransforms(); parentTransform.position += newPosition; parentTransform.SetChildrenPositions(storedChildPositions); parentTransform.SetChildrenParent(parentTransform);
This detaches children, resets transforms, moves the parent, restores positions, and reparents cleanly. The restored local positions persist relative to the new parent position.
Detaching GameObjects Gracefully
Detaching GameObjects from parents requires care to avoid erratic behavior. Children inherit absolute transformations from ancestors higher up in the hierarchy. Special handling prevents explosions upon severing links.
Dangers of unparenting incorrectly
When detached, child GameObjects retain accumulated rotations, scales, and positions. Erroneously absolute transformations cause detached objects to leap away or distort dramatically. Transforms should reset before detaching to avoid problems.
Clearing transforms on separation
Upon parent detachment, child Update() events could call ResetTransforms() to scrub inherited transformations. Alternatively, the OnDetachFromParent() event triggers automatically to handle cleansing. See examples below for implementation details.
Using OnDetachFromParent() safely
Upon parent detachment, OnDetachFromParent() event handlers reset child transformations. This safely neutralizes accumulation from lost ancestors higher up in the hierarchy. Alternatives like Start() assume detached children properly parented after loading, risky.