What is a Coordinate System?
A coordinate system is a reference for expressing an object's position. Unity uses two coordinate systems: World Space and Local Space. Understanding the difference between them allows you to move and place objects accurately.
Basic Concepts
- World Space: Absolute position in the entire scene (reference shared by all objects)
- Local Space: Relative position based on parent object (affected by parent's rotation/movement)
- Coordinate Conversion: Converting between local ↔ world coordinates
World Space
transform.position
using UnityEngine;
public class WorldPosition : MonoBehaviour
{
void Start()
{
// Position in world space (absolute position)
Vector3 worldPos = transform.position;
Debug.Log($"World position: {worldPos}");
// Set directly in world coordinates
transform.position = new Vector3(5, 0, 3);
}
}
Characteristics:
- Absolute position in the entire scene
- Independent of parent object's position/rotation
- All objects use the same reference
World Space Example
using UnityEngine;
public class WorldSpaceExample : MonoBehaviour
{
public Transform target;
void Update()
{
// Move in world coordinates
transform.position = new Vector3(0, 0, 0); // Scene origin
// Calculate distance in world coordinates
if (target != null)
{
float distance = Vector3.Distance(transform.position, target.position);
Debug.Log($"World coordinate distance: {distance}");
}
}
}
Local Space
transform.localPosition
using UnityEngine;
public class LocalPosition : MonoBehaviour
{
void Start()
{
// Position in local space (relative to parent)
Vector3 localPos = transform.localPosition;
Debug.Log($"Local position: {localPos}");
// Set directly in local coordinates
transform.localPosition = new Vector3(1, 0, 0);
}
}
Characteristics:
- Relative position based on parent object
- Local coordinate axes rotate when parent rotates
- Local coordinate origin moves when parent moves
Local Space Example
using UnityEngine;
public class LocalSpaceExample : MonoBehaviour
{
void Start()
{
// Move 2 units to the right relative to parent
transform.localPosition = new Vector3(2, 0, 0);
// When parent rotates, local coordinate axes also rotate
// When parent moves, local coordinate origin also moves
}
}
World vs Local Coordinates Comparison
Basic Comparison
using UnityEngine;
public class CoordinateComparison : MonoBehaviour
{
void Start()
{
// World coordinates (absolute position)
Vector3 worldPos = transform.position;
Debug.Log($"World coordinates: {worldPos}");
// Local coordinates (relative to parent)
Vector3 localPos = transform.localPosition;
Debug.Log($"Local coordinates: {localPos}");
// Values may differ when parent exists
// Values are the same when no parent exists
}
}
Difference When Parent Exists
using UnityEngine;
public class ParentChildExample : MonoBehaviour
{
public Transform parentObject;
void Start()
{
// Create child object
GameObject child = new GameObject("Child");
child.transform.SetParent(parentObject);
// Set in local coordinates (relative to parent)
child.transform.localPosition = new Vector3(1, 0, 0);
// If parent is at (5, 0, 0)
// Child's world coordinates become (6, 0, 0)
Debug.Log($"Child local coordinates: {child.transform.localPosition}");
Debug.Log($"Child world coordinates: {child.transform.position}");
}
}
Coordinate Conversion
Local → World Conversion
using UnityEngine;
public class LocalToWorld : MonoBehaviour
{
void Start()
{
// Local coordinates
Vector3 localPos = new Vector3(1, 0, 0);
// Convert local to world coordinates
Vector3 worldPos = transform.TransformPoint(localPos);
Debug.Log($"Local coordinates: {localPos}");
Debug.Log($"World coordinates: {worldPos}");
}
}
World → Local Conversion
using UnityEngine;
public class WorldToLocal : MonoBehaviour
{
void Start()
{
// World coordinates
Vector3 worldPos = new Vector3(5, 0, 3);
// Convert world to local coordinates
Vector3 localPos = transform.InverseTransformPoint(worldPos);
Debug.Log($"World coordinates: {worldPos}");
Debug.Log($"Local coordinates: {localPos}");
}
}
TransformPoint() vs InverseTransformPoint()
using UnityEngine;
public class TransformPointExample : MonoBehaviour
{
void Start()
{
Vector3 localPos = new Vector3(1, 0, 0);
// Local → World conversion
Vector3 worldPos = transform.TransformPoint(localPos);
// World → Local conversion (inverse)
Vector3 backToLocal = transform.InverseTransformPoint(worldPos);
// Should be same as original value
Debug.Log($"Original local: {localPos}");
Debug.Log($"Converted world: {worldPos}");
Debug.Log($"Back to local: {backToLocal}");
}
}
Direction Vector Conversion
TransformDirection() - Direction Vector Conversion
using UnityEngine;
public class TransformDirection : MonoBehaviour
{
void Start()
{
// Local direction vector (direction, not position)
Vector3 localDirection = Vector3.forward; // Local Z-axis direction
// Convert local direction to world direction
Vector3 worldDirection = transform.TransformDirection(localDirection);
Debug.Log($"Local direction: {localDirection}");
Debug.Log($"World direction: {worldDirection}");
}
}
InverseTransformDirection() - Inverse Direction Conversion
using UnityEngine;
public class InverseTransformDirection : MonoBehaviour
{
void Start()
{
// World direction vector
Vector3 worldDirection = Vector3.forward;
// Convert world direction to local direction
Vector3 localDirection = transform.InverseTransformDirection(worldDirection);
Debug.Log($"World direction: {worldDirection}");
Debug.Log($"Local direction: {localDirection}");
}
}
Practical Usage Examples
Example 1: Placing Child Relative to Parent
using UnityEngine;
public class ChildPlacement : MonoBehaviour
{
public GameObject childPrefab;
void Start()
{
// Create child object
GameObject child = Instantiate(childPrefab);
child.transform.SetParent(transform);
// Place 2 units to the right relative to parent (local coordinates)
child.transform.localPosition = new Vector3(2, 0, 0);
// Child maintains position relative to parent even when parent rotates/moves
}
}
Example 2: Setting Absolute Position in World Coordinates
using UnityEngine;
public class AbsolutePosition : MonoBehaviour
{
void Start()
{
// Place at specific position in scene (world coordinates)
transform.position = new Vector3(10, 0, 5);
// World coordinates are absolute even with parent
// Object stays at (10, 0, 5) even if parent moves
}
}
Example 3: Effect of Parent Rotation on Local Coordinates
using UnityEngine;
public class RotationEffect : MonoBehaviour
{
public Transform parent;
public Transform child;
void Start()
{
// Set child as parent's child
child.SetParent(parent);
// Place in local coordinates (right relative to parent)
child.localPosition = new Vector3(2, 0, 0);
// Rotate parent 90 degrees
parent.Rotate(0, 90, 0);
// Child's local coordinates don't change but
// world coordinates change according to parent's rotation
Debug.Log($"Child local coordinates: {child.localPosition}");
Debug.Log($"Child world coordinates: {child.position}");
}
}
Example 4: Placing Camera Relative to Player
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform player;
public Vector3 offset = new Vector3(0, 5, -10);
void LateUpdate()
{
// Place camera based on player's world coordinates
transform.position = player.position + offset;
// Or use local coordinates (set camera as player's child)
// transform.localPosition = offset;
}
}
Example 5: Distance Calculation in World Coordinates
using UnityEngine;
public class DistanceCalculation : MonoBehaviour
{
public Transform target1;
public Transform target2;
void Update()
{
// Calculate distance in world coordinates
float distance = Vector3.Distance(target1.position, target2.position);
Debug.Log($"Distance between objects: {distance}");
// Cannot calculate distance in local coordinates (references may differ)
}
}
transform.Translate() and Coordinate Systems
Translate() Coordinate System Options
using UnityEngine;
public class TranslateSpace : MonoBehaviour
{
void Update()
{
// Space.World: Move relative to world coordinate system
transform.Translate(1, 0, 0, Space.World);
// Space.Self: Move relative to local coordinate system (default)
transform.Translate(1, 0, 0, Space.Self);
// Or
transform.Translate(1, 0, 0); // Default is Space.Self
}
}
World Space Movement vs Local Space Movement
using UnityEngine;
public class TranslateComparison : MonoBehaviour
{
void Update()
{
// Method 1: World space (independent of rotation)
if (Input.GetKey(KeyCode.W))
{
transform.Translate(0, 0, 1 * Time.deltaTime, Space.World);
}
// Method 2: Local space (direction changes with rotation)
if (Input.GetKey(KeyCode.S))
{
transform.Translate(0, 0, -1 * Time.deltaTime, Space.Self);
}
}
}
Notes
- When no parent:
positionandlocalPositionhave the same value - When parent exists:
positionis world coordinates,localPositionis relative to parent - Effect of rotation: When parent rotates, local coordinate axes also rotate, changing direction
- Effect of movement: When parent moves, local coordinate origin also moves
Practical Tips
Tip 1: When to Use Local Coordinates
using UnityEngine;
public class WhenToUseLocal : MonoBehaviour
{
// Use local coordinates when:
// 1. Placing child relative to parent
// 2. Child should move/rotate with parent
// 3. Placing UI elements relative to parent panel
void SetupUI()
{
GameObject button = new GameObject("Button");
button.transform.SetParent(transform);
// Place relative to parent panel (local coordinates)
button.transform.localPosition = new Vector3(100, -50, 0);
}
}
Tip 2: When to Use World Coordinates
using UnityEngine;
public class WhenToUseWorld : MonoBehaviour
{
// Use world coordinates when:
// 1. Placing at absolute position in scene
// 2. Calculating distance to other objects
// 3. Position must be maintained regardless of parent
void SpawnEnemy()
{
GameObject enemy = new GameObject("Enemy");
// Place at specific position in scene (world coordinates)
enemy.transform.position = new Vector3(10, 0, 5);
// Calculate distance to player
float distance = Vector3.Distance(
enemy.transform.position,
transform.position
);
}
}
Tip 3: Using Coordinate Conversion
using UnityEngine;
public class CoordinateConversion : MonoBehaviour
{
public Transform target;
void Update()
{
// Convert target's world coordinates to my local coordinates
Vector3 localTargetPos = transform.InverseTransformPoint(target.position);
// Check which direction target is in my local coordinate system
if (localTargetPos.x > 0)
{
Debug.Log("Target is on the right");
}
else if (localTargetPos.x < 0)
{
Debug.Log("Target is on the left");
}
}
}