Component
Independent building blocks attached to a GameObject — each Component defines one slice of behavior, so you build games with Composition over Inheritance.
Imagine...
A Component is like an upgrade module on a race car. The chassis (GameObject) does nothing on its own — but once you bolt on an engine (Rigidbody), wheels (Collider), steering (Script), and lights (Light), the car has complete behavior. Each module works independently: unscrew the lights and the engine keeps running.
The concept in detail
Components are the heart of Unity’s architecture. Instead of a giant inheritance tree, Unity encourages combining small independent components — Composition over Inheritance.
Every Component inherits from UnityEngine.Component, so they all can reach
gameObject (the host object) and transform.
To grab a reference: GetComponent<T>(). Search children:
GetComponentInChildren<T>(). Search parents:
GetComponentInParent<T>().
The key skill: knowing
when to split a large script into several small Components.
Instead of a 500-line PlayerController → split into PlayerMovement,
PlayerCombat, PlayerHealth.
Composition vs Inheritance
❌ Inheritance (Complex)
✅ Composition (Unity)
Hands-on steps
Attach a Component from the Inspector
Select the GO → Add Component → search by name (Rigidbody, Audio Source...).
Cache with GetComponent in Awake()
_rb = GetComponent<Rigidbody>(); store it in a private field.
Enable / disable a Component
component.enabled = false/true — does not remove it, only disables it temporarily.
Talk through Interfaces for loose coupling
Avoid hard dependencies between scripts — use IDamageable, IInteractable...
Interactive simulator
Toggle Components on and off to see the character's behavior change. Watch the description for the current mix.
Toggle Components on GameObject "Player"
Current behavior
Code example
Basicusing UnityEngine;
public class ComponentBasics : MonoBehaviour
{
// Cache: fetch the component once, not every frame
private Rigidbody _rb;
private Collider _col;
private Renderer _renderer;
void Awake()
{
_rb = GetComponent<Rigidbody>();
_col = GetComponent<Collider>();
_renderer = GetComponent<Renderer>();
}
void Start()
{
// Null-check before use (safe)
if (_rb != null) _rb.mass = 2f;
_renderer.enabled = false; // hide the object
_col.enabled = false; // disable collisions
}
public void MakeInvincible()
{
// Disable the AI script (do not remove the component)
EnemyAI ai = GetComponent<EnemyAI>();
if (ai != null) ai.enabled = false;
}
}Code example
Advancedusing UnityEngine;
// Interface: a contract for any component that can take damage
public interface IDamageable
{
void TakeDamage(int amount);
}
// Health component: only manages HP, knows nothing about combat
public class Health : MonoBehaviour, IDamageable
{
[SerializeField] private int maxHP = 100;
private int _currentHP;
void Awake() => _currentHP = maxHP;
public void TakeDamage(int amount)
{
_currentHP -= amount;
if (_currentHP <= 0) Destroy(gameObject);
}
}
// Bullet component: deals damage without knowing Health exists
public class Bullet : MonoBehaviour
{
[SerializeField] private int damage = 25;
void OnCollisionEnter(Collision col)
{
// Ask: does this object implement IDamageable? → loose coupling
col.gameObject.GetComponent<IDamageable>()?.TakeDamage(damage);
Destroy(gameObject);
}
}📌 Quick recap
- ▸Component = independent module attached to a GameObject
- ▸Prefer Composition (many small components) over a deep inheritance chain
- ▸Always cache in a private field inside
Awake() - ▸Use Interfaces so components talk without depending on each other directly
⚠️ Common mistakes
❌ One script doing too many jobs
A 500-line script that owns movement, HP, guns, and UI
✅ Split into PlayerMovement, PlayerHealth, PlayerWeapon
❌ GetComponent<>() inside Update()
NullReferenceException if the component is not attached
✅ Cache in Awake() and null-check before use