Lesson 6 - Transform: Position, Rotation and Scale

The component every GameObject has: what the Inspector's numbers actually mean, why local and world values differ the moment something is parented, how rotation is really stored, and what an object's own forward direction is.

Subject: Unity Game Engine · 62 slides · code lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. The Transform: Position, Rotation, Scale

Title

Unity - Lesson 6

The one component everything has - and the local/world split hiding inside it.

2. What you will be able to do

Objectives

You got the Transform question right in the diagnostic. This lesson exists because the next one - Vector3 - was 1 out of 3, and every direction calculation starts from a Transform.

  1. Say what the Inspector's Position, Rotation and Scale fields actually mean
  2. Predict the difference between position and localPosition for a parented object
  3. Explain why lossyScale is read-only and why it is called lossy
  4. Say what a rotation really is, and why setting eulerAngles.x alone does not compile
  5. Use transform.forward, right and up and know whose axes they are

3. Answer from memory

Warm-up

Before the deck tells you anything.

Discussion prompt

You drag a cube onto another cube in the Hierarchy, and it visibly jumps to a new place. What do you think happened, and what number changed?

Hint: The Inspector's Position field means something different after the drag.

Answer:

Nothing about the child's world position changed at all - dragging in the Hierarchy keeps the object exactly where it was on screen.

What changed is the meaning of the numbers: Position now reads relative to the parent, so the Inspector shows different figures for the same place. If the object DID visibly jump, that is the other case - SetParent(parent, false) from code, which keeps the numbers and moves the object.

4. What the Transform holds

Section

Part 1

5. Three questions, one component

Concept

The Transform answers where, which way and how big. It holds nothing else - no velocity, no mass, no momentum. Those live on the Rigidbody, and lesson 3 covered who is allowed to write which.

Inspector fieldproperty in codetype
Positiontransform.localPositionVector3
Rotationtransform.localEulerAnglesVector3 of degrees
Scaletransform.localScaleVector3

Notice every row says local. The Inspector shows local values - which is invisible until the object has a parent.

Unity Manual - Transform component reference Transform

6. Two ways to give an address

Intuition

'Third door on the left' is a local address. It is only meaningful once you know which corridor you are in - but it stays correct if the whole building is picked up and moved.

'52.3 degrees north, 4.9 east' is a world address. It is meaningful anywhere and never depends on context, but it has to be recomputed the moment anything above it moves.

Unity keeps both. The Inspector shows you the local one because that is the one you type; code usually wants the world one because that is where things actually are.

7. Predict: the child in the rotated parent

Prediction

Figure (svg): A parent cube rotated 90 degrees with a child offset along the parent's local X, showing the child's world position is along world minus Z

Same object, two answers: local (1, 0, 0) and world (2, 1, -2).

Parent at (2, 1, 0), rotated 90 degrees about Y, scaled 2. Child with localPosition = (1, 0, 0).

Predict first

What is the child's world position?

  • (3, 1, 0)
  • (2, 1, -2)
  • (4, 1, 0)
  • (1, 0, 0)

Correct: (2, 1, -2).

Why: Three things happen in order: the local offset is scaled by the parent's 2, giving (2, 0, 0); then rotated by the parent's 90 degrees about Y, which sends +X to -Z, giving (0, 0, -2); then added to the parent's own position (2, 1, 0). Scale, then rotate, then translate - always in that order.

8. Six properties, three pairs

Concept

Every one of the three questions has a local answer and a world answer.

local (Inspector)world (usually what code wants)note
localPositionpositionboth writable
localRotationrotationQuaternions
localEulerAngleseulerAnglesdegrees, a view of the Quaternion
localScalelossyScalelossyScale is read-only

With no parent, each pair holds identical values - which is exactly why this distinction stays invisible right up until it matters.

Unity Scripting API - Transform Transform

9. Match the question to the property

Matching

Match the pairs

Which property answers each question?

  • q1. Where is this in the world, for a distance calculation?
  • q2. What does the Inspector's Position field show?
  • q3. How big did this end up on screen?
  • q4. What did I type into the Scale field?
  • p1. transform.position
  • p2. transform.localPosition
  • p3. transform.lossyScale
  • p4. transform.localScale

Why: Anything involving another object - distance, direction, aiming - wants world values, because the two objects may sit under different parents. Anything about this object's own setup - an offset from its parent, a size you typed - is local.

10. Print both, side by side

Worked example

The lab's probe prints all six for a parented child and an unparented control.

void Start()
{
    Debug.Log($"localPosition {transform.localPosition}");   // (1.00, 0.00, 0.00)
    Debug.Log($"position      {transform.position}");        // (2.00, 1.00, -2.00)
    Debug.Log($"localScale    {transform.localScale}");      // (0.50, 0.50, 0.50)
    Debug.Log($"lossyScale    {transform.lossyScale}");      // (1.00, 1.00, 1.00)
}
propertyChild (parented)Free cube (no parent)
localPosition(1.00, 0.00, 0.00)(-3.00, 1.00, 0.00)
position(2.00, 1.00, -2.00)(-3.00, 1.00, 0.00)
localScale(0.50, 0.50, 0.50)(0.50, 0.50, 0.50)
lossyScale(1.00, 1.00, 1.00)(0.50, 0.50, 0.50)
eulerAngles(0, 90, 0)(0, 0, 0)

Read the right column first

Why: With no parent every pair agrees. That column is what a beginner's whole world looks like, which is why the left column arrives as a shock.

11. Why does the child report a 90-degree rotation?

Explain it to yourself

Discussion prompt

Nobody rotated the child. Its localEulerAngles are (0, 0, 0). So why does its world eulerAngles read (0, 90, 0)?

Answer:

Because 'not rotated relative to my parent' and 'not rotated relative to the world' are different claims. The child is perfectly aligned with its parent, and the parent is turned 90 degrees - so the child is too.

This is why transform.forward on a child points wherever the parent is facing. The child's own axes are its parent's axes, until it rotates itself.

12. Local or world?

Sorting

Sort each line of code by which kind of value it should use.

Sort into buckets

Which value does each job need?

World values
Distance from the player to an enemy; Direction from a turret to its target
Local values
Offset of a gun from the hand that holds it; A door's open angle relative to its frame
world
It involves two objects that may live anywhere in the hierarchy. Comparing their local values would be comparing offsets from two different parents, which is meaningless.
local
It is a relationship between a child and its own parent. Expressing it locally means it keeps working when the parent moves, rotates or is carried into another scene.

13. Trap: comparing local positions of unrelated objects

Trap

The trap

Both objects have a position. Subtract them and you get the distance.

// player is under 'Level/Spawn', enemy is under 'Level/Rooms/Room3'
float distance = Vector3.Distance(
    player.localPosition, enemy.localPosition);      // meaningless

Each of those is an offset from a different parent, so the subtraction compares two numbers that were never in the same coordinate system.

The fix

Use world positions whenever two different objects are involved.

float distance = Vector3.Distance(
    player.position, enemy.position);                // correct
how many objects involveduse
one, relative to its parentlocal values
two or moreworld values, always
one, relative to the worldworld values

14. Find the coordinate bug

Error analysis

A door script. The door is a child of a moving lift.

Annotate

  • Vector3.right is the WORLD +X axis. If the lift is rotated, the door slides sideways in the world rather than along its own frame - it can open into a wall.
  • The fix is transform.right, which is this object's own +X in world coordinates - or transform.Translate(Vector3.right * 1.5f, Space.Self), which means the same thing.
  • A second issue: writing world position on a child of a moving parent fights the parent. Setting localPosition keeps the door correct as the lift travels.

Vector3.right and transform.right differ by exactly one word and by the entire question of whose axes you meant.

15. Complete the local/world matrix

Comparison

Comparison matrix

With no parentWith a rotated, scaled parent
localPosition vs positionidenticaldifferent
localScale vs lossyScaleidenticaldifferent
Can you write it?both writablelossyScale is read-only

16. Parenting and the hierarchy

Section

Part 2

17. A child is measured from its parent

Concept

Parenting is not decoration in the Hierarchy panel. It changes what a child's numbers mean: from then on, the child's position, rotation and scale are all relative to the parent.

Move the parent and the child comes along, with its local numbers unchanged. That is the whole feature - and it is why a character's hand can hold a sword without any code.

18. A passenger on a ship

Intuition

A passenger standing in a cabin does not move relative to the ship, however far the ship sails. Their cabin address never changes; their latitude and longitude change constantly.

localPosition is the cabin address. position is the latitude and longitude. Both are true at once, and asking which is 'the real one' is the wrong question.

19. Predict: SetParent with the flag

Prediction

A sphere at world (0, 1, -3) is parented to a cube using child.SetParent(parent, worldPositionStays: false).

Predict first

What happens on screen?

  • Nothing visible - it stays where it is
  • It jumps to a new world position
  • It is destroyed and re-created
  • Its scale changes but not its position

Correct: It jumps.

Why: With worldPositionStays false, Unity keeps the child's LOCAL numbers and lets the world position land wherever those numbers point relative to the new parent. Pass true and you get the opposite: the object stays on screen and its local numbers are rewritten. Dragging in the Hierarchy is the true version.

20. Both versions, measured

Worked example

The lab runs the same call twice with only the flag changed.

Vector3 worldBefore = child.position;
Vector3 localBefore = child.localPosition;

child.SetParent(newParent, worldPositionStays);

Debug.Log($"world {worldBefore} -> {child.position}");
Debug.Log($"local {localBefore} -> {child.localPosition}");
flagworld positionlocalPositionwhat it is for
trueunchangedrewrittenpicking something up without moving it
falsejumpsunchangedsnapping to a socket: hand, holster, slot

Neither is the right answer in general

Why: They are two different intentions. 'Attach without moving' and 'snap into place' are both things you want, on different days.

Unity Scripting API - Transform.SetParent SetParent

21. Watch what stays fixed as the parent moves

Invariant

Parent moves from x = 2 to x = 5 with the child attached. One row does not move.

Step through it

Which value is invariant as the parent travels, and why is that the point of parenting?

  1. start
  2. parent moves 1
  3. parent moves 2 more

localPosition is the invariant. That is what 'attached' means, and it is why you never need code to make a passenger ride a lift.

22. lossyScale, and why lossy

Concept

Figure (svg): Three nested boxes showing localScale multiplying down the hierarchy to give lossyScale

2 x 0.5 = 1, then 1 x 3 = 3. lossyScale is that product, and it is read-only.

A child's world size is every localScale above it multiplied together. Unity exposes that product as lossyScale, and it is read-only.

Unity Scripting API - Transform.lossyScale lossyScale

23. Trap: non-uniform scale on a rotated parent

Trap

The trap

Scale the parent (3, 1, 1) to make a long corridor, then rotate it 45 degrees. The children come along.

Parent   scale (3, 1, 1)   rotation Y 45
Child    scale (1, 1, 1)

Child's lossyScale reports something like (2.2, 1, 2.2)
and the child renders visibly skewed.

This is not a bug you can fix with a number. A non-uniform scale combined with a rotation is not expressible as a scale - hence 'lossy'.

The fix

Keep parents at uniform scale. Scale the mesh itself, or scale the child, or build the model at the right size.

Parent   scale (1, 1, 1)   rotation Y 45      <- uniform
Child    scale (3, 1, 1)                      <- stretch the child instead

Child's lossyScale is exactly (3, 1, 1). No skew.
wantdo
a stretched objectscale the object itself, not a rotated parent
a group you can move togetheran empty parent at scale 1
a child at a known world sizelocalScale = target / parent.lossyScale

24. Should this be parented?

Discrimination

Sort each relationship by whether parenting is the right tool.

Sort into buckets

Parent it, or keep it separate and move it in code?

Parent it
A sword held in a character's hand; UI buttons inside a panel
Keep separate, move in code
A camera following the player smoothly from behind; Crates stacked on a moving platform
parent
The child should follow exactly and instantly, with a fixed offset. Parenting does it with no code and no lag, and it survives the parent being moved, rotated or scaled.
code
You want something other than rigid attachment. A camera wants smoothing and its own rotation; crates want physics to hold them on the platform so they can be knocked off. Parenting either would look wrong.

25. Order the transform pipeline

Ranking

Unity turns a child's local values into a world position in a fixed order. Put the steps in that order.

Put in order

First step at the top.

  1. Apply the parent's scale to the local offset
  2. Rotate by the parent's rotation
  3. Add the parent's position
  4. Repeat for each parent further up the hierarchy

Why: Scale, rotate, translate - the standard order, and the reason (1, 0, 0) under a parent scaled 2 and turned 90 degrees becomes (0, 0, -2) rather than (0, 0, -1). Change the order and you get a different answer, which is why every graphics API fixes it.

26. Break this claim

Counterexample

Discussion prompt

'Parenting an object never changes how it looks.' Find a case where it does.

Hint: Two of the parent's three fields have consequences for appearance.

Answer:

Parent an object to something scaled and it changes size on screen - its localScale is unchanged, its lossyScale is not.

Parent it to something rotated with SetParent(p, false) and it both moves and turns. And in UI, parenting to a Canvas changes rendering order and layout entirely.

So the honest version: SetParent(p, true) preserves world position and rotation, but never promises anything about scale under a non-uniformly scaled parent.

27. Complete the pickup

Fill the middle

The player picks up a sword: it should snap into the hand socket, not stay where it was lying.

Fill in the blanks

void PickUp(Transform sword)
false});
sword.localPosition = Vector3.zero; // sit exactly at the socket
sword.localRotation = Quaternion.identity;
}

Why: false keeps the local numbers, so the sword's world position jumps to the hand - which is exactly what picking something up looks like. Then setting localPosition to zero puts it precisely at the socket's origin, and localRotation to identity aligns it with the hand. Using world position here would fight the hand every frame it moves.

28. Rotation, and what it really is

Section

Part 3

29. Stored as a Quaternion, shown as degrees

Concept

Unity stores rotation as a Quaternion - four numbers that describe an orientation without gimbal lock and that interpolate smoothly. The Inspector shows you Euler angles because four numbers are not readable.

Quaternion q = transform.rotation;        // (0.00, 0.71, 0.00, 0.71) for 90 about Y
Vector3 degrees = transform.eulerAngles;  // (0, 90, 0) - a readable VIEW of q
propertytypeuse it when
rotationQuaternionassigning from LookRotation, Slerp, identity
eulerAnglesVector3 degreesreading a human-friendly value, setting a whole rotation
Quaternion.Euler(x, y, z)Quaternionbuilding a rotation from degrees
Quaternion.identityQuaternionno rotation at all

Unity Manual - Rotation and orientation in Unity Rotation and orientation

30. Degrees are a printout, not the storage

Intuition

Think of eulerAngles the way you think of a decimal printout of a stored fraction. The printout is useful and readable, and converting back and forth is not always exact.

Set a rotation to 361 degrees and read it back: you get 1. Set (0, 90, 0) two different ways and you may read back (0, 90, 0) or something with tiny floating-point noise in it.

So: assign whole rotations, read eulerAngles for display, and do not build logic on reading them back.

31. Predict: reading back an angle

Prediction

transform.eulerAngles = new Vector3(0, 370, 0); then immediately Debug.Log(transform.eulerAngles.y);

Predict first

What prints?

  • 370
  • 10
  • 0
  • -350

Correct: 10.

Why: The value was converted into a Quaternion, which has no concept of 'more than one turn'. Reading back gives an equivalent angle in the 0-360 range. This is why a script that accumulates rotation by reading eulerAngles, adding, and writing back will eventually behave strangely - keep your own float and assign from it instead.

32. Rotating, and the two spaces

Worked example

transform.Rotate and transform.Translate both take a space argument, and the default is not the one people expect.

transform.Rotate(Vector3.up, 90f * Time.deltaTime, Space.World);
transform.Translate(Vector3.forward * 2f, Space.Self);    // Self is the DEFAULT
callspacemeaning
Translate(forward, Space.Self)own axesmove the way I am facing
Translate(forward, Space.World)world axesmove along world +Z whatever I am facing
Rotate(up, 90, Space.Self)own axesyaw around my own up
Rotate(up, 90, Space.World)world axesyaw around world up - what you usually want

Space.Self is the default for both

Why: Which is right for Translate on a character and often wrong for Rotate on an object that is already tilted - a tilted object rotating around its own up wanders off in a way that is hard to debug by eye.

33. Decode a Quaternion print

Notation

You will see these in the Console. You do not need to do arithmetic on them, but you should not be alarmed by them.

Annotate

  • Four components: x, y, z, w. Together they encode an axis and an angle - here, 90 degrees about the Y axis. The individual numbers are not degrees and mean nothing on their own.
  • 0.71 is roughly the square root of a half, which is what a 90-degree rotation produces. Recognising it is a party trick, not a skill - never write logic against these numbers.
  • The same rotation, converted for display. This is the line to read when debugging, and the one to compare against what you typed in the Inspector.

34. Trap: setting one axis of eulerAngles

Trap

The trap

I only want to change the pitch, so I will set the x component.

transform.eulerAngles.x = 45f;        // does not compile

eulerAngles returns a copy of a struct. Assigning to its field would modify a temporary that is immediately discarded, so C# refuses.

The fix

Build a whole Vector3 and assign that, or build a Quaternion.

Vector3 angles = transform.eulerAngles;
angles.x = 45f;
transform.eulerAngles = angles;

// or, more explicit about intent:
transform.rotation = Quaternion.Euler(45f, angles.y, angles.z);
symptomcause
'cannot modify the return value'the property returns a struct copy
same error on transform.position.x = 5identical reason - build a Vector3
works on myVector.x = 5a local variable is not a property; that is fine

35. Whose axes?

Definition probe

Sort each expression by whether it means the world's axes or this object's.

Sort into buckets

World axes, or the object's own?

World axes - fixed constants
Vector3.forward; Vector3.up
This object's axes, in world coordinates
transform.forward; transform.right
world
Vector3.forward is always (0, 0, 1) and Vector3.up is always (0, 1, 0), whatever anything is doing. They are constants, useful for fixed directions like gravity or a top-down plane.
own
transform.forward is the direction this object faces, expressed in world coordinates - so it changes as the object turns. It is what you want for 'move forwards', 'fire where I am aiming', 'is it in front of me'.

36. Two of these are true

Two truths and a lie

Eliminate the wrong options

Which claim about the Transform is false?

  • A. transform.forward is (0, 0, 1) rotated by the object's rotation.
  • B. The Transform stores an object's velocity between frames.
  • C. Every GameObject has exactly one Transform and it cannot be removed.

Survives elimination: B

Why: The Transform holds where an object IS, not how it is moving. Velocity lives on the Rigidbody, and an object with no Rigidbody has no velocity at all - it just occupies a series of positions. This is the misconception the diagnostic recorded for this topic.

37. forward, right, up - the object's own axes

Concept

Three read-only properties give you this object's axes as world-space direction vectors, each of length 1.

transform.forward   // the way it faces
transform.right     // its own +X
transform.up        // its own +Y

transform.position += transform.forward * speed * Time.deltaTime;  // walk forwards
expressionfor a cube with no rotationfor the same cube turned 90 about Y
transform.forward(0, 0, 1)(1, 0, 0)
transform.right(1, 0, 0)(0, 0, -1)
transform.up(0, 1, 0)(0, 1, 0)

The last row is worth noticing: rotating about Y leaves up alone, which is why yaw is the safe rotation for anything walking on the ground.

38. Predict the child's forward

Pattern

A child with localEulerAngles = (0, 0, 0), under a parent turned 90 degrees about Y.

Predict first

What is the child's transform.forward in world coordinates?

  • (0, 0, 1)
  • (1, 0, 0)
  • (0, 1, 0)
  • (-1, 0, 0)

Correct: (1, 0, 0) - the same way the parent faces.

Why: transform.forward is a WORLD direction, so it accounts for every rotation above the object as well as its own. A child that has not rotated itself faces exactly where its parent faces - which is what makes a gun parented to a hand fire in the direction the character is aiming, with no code at all.

39. Rotate the object, or rotate the parent?

Trade off

A turret with a base that yaws and a barrel that pitches. Weigh two designs.

Comparison matrix

One object, combined rotationTwo objects: base parent, barrel child
Yaw and pitch independentlyneeds care with Euler ordertrivial - one axis each
Barrel follows the baseyou compute itfree - parenting does it
Gimbal troublepossibleavoided
Objects in the scene12

This is the standard answer to almost every awkward rotation problem in Unity: add a parent and give each object one axis to worry about.

40. Build it in Unity

Section

Build

41. What you are about to build

Concept

A rotated, scaled parent with a child inside it, an identical free cube for comparison, and a sphere that gets adopted mid-play.

TransformProbe
Prints all six properties plus the direction vectors.
ParentingLab
SetParent with worldPositionStays true and false.

The parent's numbers are chosen so the arithmetic is checkable: position (2, 1, 0), rotation Y 90, scale 2, with the child at local (1, 0, 0). Files: unity-labs/Assets/NaruhodoLabs/Lesson06_Transform/.

42. Predict before you build

Step zero

Discussion prompt

Work out the child's world position and lossyScale on paper, from parent (2, 1, 0) / rot Y 90 / scale 2 and child local (1, 0, 0) / localScale 0.5. Show the three steps.

Hint: Scale, then rotate, then translate.

Answer:

  1. Scale: local (1, 0, 0) times the parent's 2 = (2, 0, 0)
  2. Rotate: 90 degrees about Y sends +X to -Z, giving (0, 0, -2)
  3. Translate: add the parent's (2, 1, 0) = (2, 1, -2)
  4. lossyScale: 2 times 0.5 = (1, 1, 1)

Now run the scene and check. Being right on paper before the Console agrees is the difference between knowing this and recognising it.

43. Step 1: build the parent and child

Worked example

Two cubes, one drag, four numbers.

  1. Cube Parent: Position (2, 1, 0), Rotation (0, 90, 0), Scale (2, 2, 2)
  2. Cube Child: drag it onto Parent in the Hierarchy, then set Position (1, 0, 0) and Scale (0.5, 0.5, 0.5)
  3. Add Component > Transform Probe to the child
  4. A third cube Free cube at (-3, 1, 0), Scale 0.5, also with a probe, and no parent
you typedInspector fieldwhich property
(1, 0, 0)PositionlocalPosition
(0.5, 0.5, 0.5)ScalelocalScale
nothing-position = (2, 1, -2)
nothing-lossyScale = (1, 1, 1)

44. Step 2: re-parent mid-play

Worked example

The sphere is adopted at t = 2s. Run it once with the flag true, once with it false.

child.SetParent(newParent, worldPositionStays);

Debug.Log($"world {worldBefore} -> {child.position}");
Debug.Log($"local {localBefore} -> {child.localPosition}");
flagworld beforeworld afterlocal beforelocal after
true(0, 1, -3)(0, 1, -3)(0, 1, -3)(-1.50, 0, -1.00)
false(0, 1, -3)jumps(0, 1, -3)(0, 1, -3)

One of the two columns always survives

Why: true preserves the world column; false preserves the local column. Nothing preserves both, because under a new parent they cannot both be what they were.

45. Commit before you run it

Hypothesis

During Play you drag the Parent cube around in the Scene view.

Predict first

What does the child's localPosition do?

  • Follows the parent
  • Stays exactly (1, 0, 0)
  • Goes to zero
  • Becomes the world position

Correct: Stays exactly (1, 0, 0), no matter how far the parent goes.

Why: The child's local position is its offset from the parent, and that offset is unchanged by the parent moving. Its world position changes constantly. Watching those two numbers side by side while dragging is the single clearest demonstration of the local/world split there is.

46. Where this shows up in a real game

Real world

Discussion prompt

A character carries a lamp that should swing slightly as they walk, and a UI health bar that should float above their head and always face the camera. Which is parented, which is not, and what are the local values in each case?

Answer:

  • Lamp: parented to a hand or belt bone, with a small localPosition offset and its own script adding sway on top. Parenting handles 'carried'; the script handles 'swings'.
  • Health bar: parented for position, not for rotation. Usually a child so it follows the head, with a script in LateUpdate setting its world rotation to face the camera - because a parented rotation would spin the bar as the character turns.
  • Why LateUpdate: the character has finished moving for the frame, so the bar lands in the right place with no lag - lesson 4's rule showing up again.

The pattern: parent what should follow rigidly, and override in code only the one property that should not.

47. Explain local vs world in two sentences

Explain it

Discussion prompt

A teammate says 'I moved the parent and now my child's Position shows the wrong numbers'. Answer in two sentences.

Answer:

Model answer: 'The Inspector's Position is the offset from the parent, not the world position, so it stays the same when the parent moves - which is exactly what you want, because the child keeps its place inside the group.'

'If you need where it actually is, read transform.position in code, or unparent it for a moment and look.'

48. Now break it, on purpose

Concept

Six experiments from the lab notes.

changewhat happens
Move the parent during Playthe child follows; its localPosition never changes
Set the parent's Scale to (3, 1, 1) and rotate itthe child skews and lossyScale reports odd numbers
Try to type into lossyScaleyou cannot - it is read-only
Set eulerAngles.y to 361 and read it backit reports 1
Write transform.eulerAngles.x = 45;it does not compile - build a whole Vector3
Add a Rigidbody to the child and write its position each frameyou are back in lesson 3's trap

49. One symptom, four suspects

Elimination

A gun is parented to a character's hand. When the character turns, the gun ends up pointing the wrong way.

Eliminate the wrong options

What should you check first?

  • A. The gun's firing code uses Vector3.forward instead of transform.forward.
  • B. The gun's localPosition is wrong.
  • C. The hand socket has a non-uniform scale.
  • D. The gun needs its own Rigidbody.

Survives elimination: A

Why: Vector3.forward is the world's +Z and never changes; transform.forward is the gun's own facing and rotates with the character. A gun that always fires along world +Z looks correct only while the character happens to face that way, which is why this bug reads as 'it works at the start of the level'.

50. Complete the follow script

Faded example

A camera that follows the player from behind without being parented.

Fill in the blanks

public Transform target;
public Vector3 offset = new Vector3(0f, 3f, -6f);

void LateUpdate()
position} + offset;
transform.LookAt(target);
}

Why: LateUpdate because the player moves in Update, and a camera that reads the position before the player has moved lags one frame - which players perceive as jitter. And world position because the camera and the player are two separate objects that may sit anywhere in the hierarchy, so their local values are not comparable.

51. The procedure: local or world?

Pattern

Four questions. They pick the right property every time.

  1. How many objects are involved? Two or more - world values. One, relative to its parent - local values.
  2. Am I reading the Inspector? Then you are reading local values, whatever the field is labelled.
  3. Do I mean a fixed direction or this object's own? Vector3.forward is the world's; transform.forward is the object's.
  4. Am I assigning a rotation? Assign the whole thing - Quaternion.Euler(...) or a whole Vector3 into eulerAngles. Never one component.

And when parenting: SetParent(p, true) to attach without moving, SetParent(p, false) to snap into a socket.

52. Check 1: the parented child

Check

Check your understanding

A child has localPosition (1, 0, 0). Its parent is at (2, 1, 0), rotated 90 degrees about Y, with scale 2. What does the child's transform.position report?

  • A. (1, 0, 0)
  • B. (3, 1, 0)
  • C. (2, 1, -2) (correct)
  • D. (2, 1, 0)

Answer: C

Why: Scale first: (1, 0, 0) times 2 is (2, 0, 0). Then rotate: 90 degrees about Y sends +X to -Z, giving (0, 0, -2). Then translate by the parent's position: (2, 1, -2). Scale, rotate, translate, always in that order.

Why A tempts people
That is localPosition - what the Inspector shows. The question asks for the world value, which is what code almost always wants.
Why B tempts people
This adds the local offset to the parent's position without applying the rotation or the scale. It is the answer you get by treating the parent as if it were unrotated.
Why D tempts people
That is the parent's own position, which the child would only share if its local offset were zero.

53. Check 2: what the Transform holds

Check

Check your understanding

Which of these does the Transform component store?

  • A. Position, rotation, scale and velocity
  • B. Position, rotation and scale only (correct)
  • C. Position and rotation; scale is on the Renderer
  • D. Everything about the object, including its mass

Answer: B

Why: Where it is, which way it is facing, how big it is. Velocity and mass belong to the Rigidbody, and an object with no Rigidbody has neither - it simply occupies a position that something else decides.

Why A tempts people
The misconception this lesson targets. Velocity is physics state, so it lives on the Rigidbody; lesson 3 covered which one of them is allowed to write the position.
Why C tempts people
Scale is on the Transform - it is the third field in the Inspector. The Renderer decides how the object is drawn, not how big it is.
Why D tempts people
That would make the Transform the object itself, which is lesson 1's inheritance misconception in another form. The Transform is one component among several.

54. One question to sit with

Socratic

Discussion prompt

Why does Unity store rotation as a Quaternion rather than as the three angles the Inspector shows?

Answer:

Two reasons. Gimbal lock: with three sequential angles, certain orientations lose a degree of freedom, and rotation stops behaving as it should. Quaternions have no such orientation.

Interpolation: turning smoothly from one orientation to another is a clean operation on Quaternions and an ambiguous mess on Euler angles - there are several ways to get there and they look different.

The cost is readability, which is exactly why the Inspector converts for you and why eulerAngles exists as a view.

55. Check 3: whose forward?

Check

Check your understanding

A cube is rotated 90 degrees about Y. What is transform.forward, and what is Vector3.forward?

  • A. Both are (0, 0, 1)
  • B. transform.forward is (1, 0, 0); Vector3.forward is (0, 0, 1) (correct)
  • C. transform.forward is (0, 0, 1); Vector3.forward is (1, 0, 0)
  • D. Both are (1, 0, 0)

Answer: B

Why: transform.forward is the object's own facing expressed in world coordinates, so it rotates with the object: a 90-degree yaw sends it to (1, 0, 0). Vector3.forward is the constant (0, 0, 1) and never changes for anything.

Why A tempts people
That is true only for an unrotated object - which is why this confusion survives so long in a scene where nothing has been turned yet.
Why C tempts people
Backwards. The transform one is the one that moves; the Vector3 one is the constant.
Why D tempts people
Vector3.forward is a constant of the world and cannot depend on any object's rotation.

56. A quick feel for scale

Estimation

A child sits under three parents, scaled 2, 0.5 and 3 from the top down. Its own localScale is 1.

Predict first

What is its lossyScale?

  • 1
  • 3
  • 5.5
  • 6

Correct: 3.

Why: 2 x 0.5 x 3 x 1 = 3. Scales multiply down the hierarchy, they do not add - which is why one carelessly scaled parent high up can make everything beneath it the wrong size, and why the usual advice is to keep group parents at scale 1.

57. What else do you need to know?

Missing information

Discussion prompt

Someone asks you to 'make this object twice as big'. What do you need to establish first?

Answer:

  • Twice as big as what? Its current size, or twice a specific world size - two different calculations.
  • Does it have parents? If so, localScale times 2 doubles it, but setting localScale to 2 might not - that depends on the parents' scales.
  • Does it have a Collider? A Box Collider scales with the Transform; a Character Controller or a Terrain Collider does not, and needs its own fields adjusted.
  • Is the mesh itself the right size? Scaling a Transform is a stopgap; a model imported at the wrong scale is better fixed in its import settings.

The third bullet is the one that bites in practice: an object that looks twice as big but collides at its old size is a bug that takes a long time to see.

58. What this unlocks

Concept

Lesson 7 is entirely built on this: every direction calculation subtracts two world positions, and every 'face this way' assigns a rotation.

you now havewhat it enables
local vs worlddistances and directions that are actually correct
the parenting modelcarried objects, sockets, UI hierarchies
Quaternion vs eulerAnglesrotation code that does not drift
transform.forward'move the way I am facing' - the basis of lesson 7

59. Connect it to something you know

Analogy

Match the pairs

Match each Unity idea to a familiar cousin.

  • u1. localPosition
  • u2. position
  • u3. Parenting
  • u4. lossyScale
  • o1. a relative file path
  • o2. an absolute file path
  • o3. putting a file inside a folder
  • o4. the computed size after every CSS transform above it

Why: The path analogy carries further than it looks: a relative path breaks when you compare two of them from different folders, exactly like comparing two localPositions under different parents, and moving a folder keeps every relative path inside it valid, exactly like moving a parent.

60. Draw the two coordinate systems

Connect it up

Draw it

Draw world axes in one corner. Draw a parent box somewhere else, rotated, with its own axes marked. Put a child on the parent's local +X and label both its localPosition and its world position.

61. Before you close this

Exit ticket

Predict first

Which is still shakiest?

  • local vs world position
  • lossyScale and parent scaling
  • Quaternions and eulerAngles
  • transform.forward vs Vector3.forward

Correct: Whichever you picked - the lab prints all four in one Play session; go and read the one you named.

Why: This topic tested fine, so the goal is depth rather than repair - and the fourth option in particular is the one lesson 7 needs solid, because every direction calculation there starts by deciding whose axes you meant.

62. What you can now do

Recap

You can read any Transform in the Inspector and say what it means in the world.

Lab: unity-labs/Assets/NaruhodoLabs/Lesson06_Transform/SETUP.md. Do the paper prediction before you press Play, then go to lesson 7.

Sources

  1. Unity Manual - Transform component reference
  2. Unity Scripting API - Transform
  3. Unity Scripting API - Transform.SetParent
  4. Unity Scripting API - Transform.lossyScale
  5. Unity Manual - Rotation and orientation in Unity
  6. Naruhodo Unity Labs - Lesson 06 setup notes — unity-labs/Assets/NaruhodoLabs/Lesson06_Transform/SETUP.md

Want this taught 1-on-1? Alexander tutors Unity Game Engine — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108