Components
Summary
A component is a focused, self-contained piece of behavior or data that gets attached to a game object to give it a specific capability — movement, health, rendering, audio. A game object gains its full functionality by having many components attached at once, each responsible for exactly one concern, rather than one class trying to implement everything a "player" or "enemy" needs internally.
Why This Matters
A single monolithic Enemy class trying to handle movement, health,
animation, sound, and AI all in one place becomes difficult to change
safely — a fix to how health regenerates risks breaking something unrelated
in the same file, and none of that logic can be reused for a
DestructibleCrate that also needs health but nothing else an Enemy has.
Components solve this by isolating each concern into its own small,
independently testable and reusable piece — a Health component works
identically whether it's attached to an enemy, the player, or a crate.
Mental Model
A component is a single tool clipped onto a utility belt, not a permanently built-in feature of the belt itself. A utility belt on its own holds nothing and does nothing; clipping on a flashlight, a radio, and a first-aid kit gives the wearer exactly those three capabilities, each independent of the others and each usable on a different belt entirely. Removing the radio doesn't affect the flashlight. A game object's components work the same way — independent, removable, reusable pieces of capability, not permanent, entangled features of one big class.
Core Explanation
- A component handles exactly one responsibility. A
Healthcomponent manages current/max health and damage/heal logic; it doesn't also handle movement or rendering — that separation is what makes it reusable across unrelated game objects. - Components communicate through references, not inheritance. A
MeleeAttackcomponent that needs to check the target's health gets a reference to that target'sHealthcomponent and calls its public methods — it doesn't need to inherit from anything to cooperate with it. - Multiple components combine to form full behavior. No single
component tries to be "the whole enemy" —
Health,NavMeshAgent,MeleeAttack, andEnemyAnimatorattached together produce a complete, functioning enemy, each piece replaceable independently. - A component's lifecycle is tied to the game object it's attached to. A component is created when added, receives its own initialization and per-frame callbacks while active, and is destroyed along with (or independently removed from) its game object.
Syntax / Theory
C# (Unity — MonoBehaviour components)
public class Health : MonoBehaviour
{
[SerializeField] private int maxHealth = 100;
private int current;
void Awake() => current = maxHealth;
public void TakeDamage(int amount)
{
current -= amount;
if (current <= 0) Die();
}
private void Die() => Destroy(gameObject);
}
GameObject enemy = new GameObject("Skeleton");
enemy.AddComponent<Health>(); // One focused capability.
enemy.AddComponent<MeleeAttack>(); // Another, independent capability.
C++ (Unreal — ActorComponents)
UCLASS()
class UHealthComponent : public UActorComponent
{
GENERATED_BODY()
public:
void TakeDamage(int32 Amount)
{
CurrentHealth -= Amount;
if (CurrentHealth <= 0) OnDeath();
}
private:
int32 CurrentHealth = 100;
};
Unreal's UActorComponent fills the identical role as Unity's
MonoBehaviour-derived component classes — a self-contained, attachable
unit of behavior, added to an Actor the same way AddComponent<T>() adds
one to a GameObject.
Unreal Blueprint
Adding an Actor Component in the Components panel and configuring its exposed properties is the same composition model expressed visually — a designer assembles capability from independent, reusable pieces without writing C++.
Practical Example
An interactable door is built from small, independent components that cooperate without any of them being aware of the others' internals.
public class Interactable : MonoBehaviour
{
public UnityEvent OnInteract;
public void Interact() => OnInteract?.Invoke();
}
public class DoorController : MonoBehaviour
{
public void Open() => GetComponent<Animator>().SetTrigger("Open");
}
GameObject door = new GameObject("Door");
var interactable = door.AddComponent<Interactable>();
var controller = door.AddComponent<DoorController>();
interactable.OnInteract.AddListener(controller.Open); // Composed, not inherited.
Interactable has no idea it's attached to a door specifically — it could
just as easily trigger a lever, a chest, or an NPC conversation, because it
only knows about "something happened," not what should happen in response.
Common Mistakes
- Letting one component grow to handle multiple unrelated
responsibilities. A
PlayerControllerthat handles movement, input, health, and inventory all in one script has quietly become the monolithic class components were meant to replace — split it back into focused pieces. - Reaching into another component's private state directly instead of through its public interface. Directly modifying another component's internal fields (when accessible) couples the two tightly and bypasses any validation that component's public methods were meant to enforce.
- Fetching a component reference every frame instead of caching it.
Calling
GetComponent<Health>()insideUpdate()repeatedly performs unnecessary lookup work every frame — cache the reference once (typically inAwake) and reuse it. - Creating a component with no clear single responsibility "for
convenience." A
MiscorUtilitycomponent that accumulates unrelated helper logic over time recreates the monolithic-class problem one unclear component at a time.
Game Development Example
A weapon system built from small, swappable components lets different weapon types share most of their logic while differing in exactly one piece.
public class WeaponFireComponent : MonoBehaviour
{
public IProjectile projectilePrefab; // Different weapons plug in a different projectile.
public float fireRate = 2f;
public void Fire() => Instantiate(projectilePrefab as Object, muzzle.position, muzzle.rotation);
}
A Bow and a Crossbow game object can both use the same
WeaponFireComponent, differing only in which projectilePrefab and
fireRate are configured — the firing logic itself is written once and
shared.
Best Practices
- Give every component exactly one clear responsibility, reflected in its
name (
Health, notEnemyStuff). - Prefer components communicating through public methods/events over reaching into each other's internal state.
- Cache component references once during initialization rather than looking them up repeatedly during per-frame logic.
- Favor small, reusable components over a large one, even if it means a game object ends up with many components attached.
Exercises
- Refactor a hypothetical monolithic
Playerclass that handles movement, health, and inventory into three separate components, and describe how each could now be reused on a different kind of game object. - Take the
Interactable/DoorControllerexample and reuseInteractableon aChestgame object with a different listener method — confirmInteractableitself needs no changes. - You're designing a
StatusEffectsystem (poison, stun, slow) that needs to modify a character's movement speed and deal periodic damage. Decide whether each status effect should be its own component or whether oneStatusEffectManagercomponent should hold all active effects internally, and justify the trade-off. - Research the "Entity Component System" (ECS) architecture and explain, in your own words, one way it differs from the MonoBehaviour/ActorComponent style of composition covered here.
Related Concepts
- Game Objects — the container components attach to; a component has no meaning or place to exist without a game object hosting it.
- Composition vs Inheritance — the component model is the concrete, engine-level embodiment of favoring composition over a rigid inheritance hierarchy for gameplay capability.
- Prefabs — a prefab is typically a game object with a specific, reusable set of components pre-configured, saved as a template for repeated instantiation.
Further Reading
KNOWLEDGE_SCHEMA.md— GDKB's concept maturity ladder and cross-linking rules, which this document follows.- Unity documentation — Using Components: https://docs.unity3d.com/Manual/Components.html
- Unreal Engine documentation — Components: https://dev.epicgames.com/documentation/en-us/unreal-engine/components-in-unreal-engine