Topic 2 of 15 8 min beginner

The Transform

Position, rotation, scale, and parenting

The Transform is the only component every GameObject is guaranteed to have. It answers three questions: where the object is, which way it faces, and how big it is. It also defines the parent-child hierarchy you see in the Hierarchy window.

Local space and world space

This is the single most common source of "why is my object in the wrong place" confusion. Every transform has two sets of coordinates.

PropertyWhat it meansNote
transform.positionWhere it is in the worldAbsolute, regardless of parents
transform.localPositionOffset from its parentWhat the Inspector shows you
transform.rotationWorld rotation (Quaternion)Absolute facing
transform.localRotationRotation relative to parentAlso a Quaternion
transform.localScaleScale relative to parentThe one you normally set
transform.lossyScaleApproximate world scaleRead-only, and lies under skewed parents
The Inspector always shows local values. An object at local position (0, 0, 0) sits exactly on its parent, which may be nowhere near the world origin.

Moving things

There are three common ways to move a transform, and they are not interchangeable.

C#
using UnityEngine;

public class MoveExamples : MonoBehaviour
{
    [SerializeField] private float speed = 5f;

    private void Update()
    {
        // 1. Teleport - set the position outright
        transform.position = new Vector3(0f, 1f, 0f);

        // 2. Offset - add to the current position
        transform.Translate(Vector3.forward * speed * Time.deltaTime);

        // 3. Interpolate - ease toward a target
        transform.position = Vector3.MoveTowards(
            transform.position,
            target.position,
            speed * Time.deltaTime
        );
    }
}
You cannot modify position in place. transform.position.x = 5f; does not compile, because position returns a copy of a struct. Build a new Vector3 and assign the whole thing.
C#
// Wrong - will not compile
// transform.position.x = 5f;

// Right - replace the whole vector
Vector3 p = transform.position;
p.x = 5f;
transform.position = p;

Always multiply by Time.deltaTime

Update runs once per rendered frame, and frame rate varies between machines and moments. If you move by a fixed amount per frame, your game runs faster on a faster computer — which is a real bug, not a curiosity.

C#
private void Update()
{
    // 5 units per SECOND, on every machine
    transform.Translate(Vector3.forward * 5f * Time.deltaTime);
}

Rotation, and why Quaternions

transform.rotation is a Quaternion, not the three angles you see in the Inspector. Quaternions avoid gimbal lock and interpolate cleanly, but they are not human-readable — you should essentially never set their x, y, z, w by hand.

C#
// Build a rotation from readable angles
transform.rotation = Quaternion.Euler(0f, 90f, 0f);

// Turn a little each frame
transform.Rotate(0f, 90f * Time.deltaTime, 0f);

// Face a target
Vector3 direction = target.position - transform.position;
transform.rotation = Quaternion.LookRotation(direction);

// Ease toward a target rotation
transform.rotation = Quaternion.Slerp(
    transform.rotation,
    targetRotation,
    5f * Time.deltaTime
);
Reading transform.eulerAngles back does not always give you the numbers you set. Quaternion.Euler(0, 190, 0) may read back as (180, 350, 180) — the same orientation, described differently. Store your own angle in a field if you need to accumulate it.

Direction vectors

Every transform exposes its own axes, which is almost always what you want for movement relative to where something is facing.

VectorPoints towardNote
transform.forwardThe object’s own +ZWhere it is facing
transform.rightThe object’s own +XIts right-hand side
transform.upThe object’s own +YIts own up, not the world’s
Vector3.forwardWorld +ZFixed, ignores rotation
Vector3.upWorld +YUse for gravity and jumping

Parenting

Making one transform a child of another means it inherits position, rotation, and scale. Move the parent and the children come along.

C#
// Attach to a parent, keeping the current world position
weapon.transform.SetParent(hand, worldPositionStays: true);

// Attach and snap to the parent's local origin instead
weapon.transform.SetParent(hand, false);
weapon.transform.localPosition = Vector3.zero;

// Detach
weapon.transform.SetParent(null);
Picking up an item is usually just SetParent(hand, false) plus zeroing the local position. Dropping it is SetParent(null). No custom follow code needed.

Two traps worth knowing early

Never scale a physics object non-uniformly

Colliders are scaled by the transform, and non-uniform scale — for example (2, 1, 1) — forces Unity to approximate the collision shape. Capsule and sphere colliders behave especially badly.

Worse, scaling a parent scales every child collider too. If physics feels subtly wrong, check for a scaled parent before you blame the physics settings. Scale the mesh in your 3D tool instead, and keep game object scale at (1, 1, 1).

Do not move Rigidbodies with the Transform

Setting transform.position on an object with a Rigidbody teleports it past the physics engine. Collisions get missed, and fast objects pass straight through walls.

Use rb.MovePosition() and rb.MoveRotation() in FixedUpdate instead, or apply forces and let physics resolve it. This is covered properly in the Colliders & Rigidbodies topic.

What to take away

  • The Inspector shows local values; transform.position is world.
  • Multiply every per-frame movement by Time.deltaTime.
  • You cannot assign to transform.position.x — replace the whole vector.
  • Build rotations with Quaternion.Euler or LookRotation, never by hand.
  • transform.forward is object-relative; Vector3.forward is world-fixed.
  • Keep scale uniform on anything with a collider.