Unity Beginner Project: Build Health, Damage, and a Simple Enemy
This guide shows you how to build a simple but real combat foundation in Unity. You will create a player with health, an enemy that damages the player on contact, temporary invulnerability after getting hit, knockback, and a basic health UI.
This is not a full combat system yet. It is the reliable core you can later use for action RPGs, platformers, arena games, and survival prototypes.
What You Will Make
By the end you will have:
A player with max health and current health.
An enemy that hurts the player.
Invulnerability frames so the player does not lose all health instantly.
Knockback so hits have physical feedback.
A UI text label showing health.
Step 1: Prepare the Scene
Create a Unity 2D project or use an existing 2D test scene.
Create:
Player: blue square or capsule
Enemy: red square
Ground or simple room walls if your game needs collision boundaries
On the Player:
Add Rigidbody2D
Add BoxCollider2D or CapsuleCollider2D
Set Gravity Scale depending on your game:
Top-down: 0
Platformer: keep gravity enabled
On the Enemy:
Add Rigidbody2D
Add Collider2D
For a top-down test, set Gravity Scale to 0
Step 2: Create the Health Component
Create Health.cs.
CSHARP
1using System;2using UnityEngine;34public class Health : MonoBehaviour5{6[SerializeField] private int maxHealth =5;78 public int CurrentHealth { get; private set;}9 public int MaxHealth => maxHealth;
Attach Health to the Player.
Why use events? Because health should not need to know about UI, sound effects, animations, or game-over screens. Other systems can listen and respond.
Step 3: Add a Damage Receiver With Invulnerability
If the enemy stays touching the player, OnCollisionStay2D could damage every frame. That feels unfair. Instead, give the player invulnerability after taking damage.
Create PlayerDamageReceiver.cs.
CSHARP
1using System.Collections;2using UnityEngine;34public class PlayerDamageReceiver : MonoBehaviour5
Attach it to the Player.
If your Unity version uses velocity instead of linearVelocity, replace this line:
CSHARP
1body.linearVelocity = Vector2.zero;
with:
CSHARP
1body.velocity = Vector2.zero;
Step 4: Make the Enemy Deal Contact Damage
Create ContactDamage.cs.
CSHARP
1using UnityEngine;23public class ContactDamage : MonoBehaviour4{5[SerializeField] private int damage =1;6
Attach this to the Enemy.
Now when the enemy touches the player, the player loses health and gets pushed away.
Step 5: Add a Tiny Enemy Movement Script
An enemy that just sits still is not very useful. Create a basic patrol.
Create EnemyPatrol.cs.
CSHARP
1using UnityEngine;23public class EnemyPatrol : MonoBehaviour4{5[SerializeField] private Transform pointA;
Create two empty GameObjects named PatrolA and PatrolB, place them apart, and assign them to the enemy.
Step 6: Show Health on Screen
Create a Canvas:
Right-click Hierarchy.
Choose UI > Canvas.
Inside it, create UI > Text - TextMeshPro.
Name it HealthText.
If Unity asks to import TMP essentials, accept.
Create HealthTextUI.cs.
CSHARP
1using TMPro;2using UnityEngine;34public class HealthTextUI : MonoBehaviour5{6[SerializeField private Health playerHealth
Attach it to a UI manager object, then assign:
Player Health: the Player object with Health
Label: your TextMeshPro label
Step 7: Handle Death
For now, keep death simple.
Create PlayerDeathHandler.cs.
CSHARP
1using UnityEngine;2using UnityEngine.SceneManagement;34public class PlayerDeathHandler : MonoBehaviour5{6 private Health health;
Attach it to the Player.
Now the scene restarts when health reaches zero.
Step 8: Test Like a Designer
Do not only test if the code runs. Test if it feels fair.
Try these:
Touch the enemy once. Do you lose exactly one health?
Stay touching the enemy. Do invulnerability frames prevent instant death?
Is knockback strong enough to separate the player?
Is the enemy speed readable?
Does the health UI update immediately?
Step 9: Improve the Feel
Small upgrades that make a big difference:
Flash the player sprite during invulnerability.
Play a hit sound.
Shake the camera lightly on damage.
Add enemy wind-up before contact damage.
Add a hurt animation before restarting the scene.
The key lesson: combat is not just damage numbers. A good first combat loop tells the player what happened, gives them time to recover, and lets them understand how to avoid the next hit.