Willkommen zu diesem Schritt-für-Schritt Unity 2D Tutorial für Einsteiger! In diesem Kurs erstellen wir gemeinsam ein einfaches, aber spannendes Spiel — einen klassischen Weltraum-Shooter. Du lernst, wie du das Raumschiff steuerst, auf Gegner schießt und die integrierte 2D-Physik von Unity nutzt.
Du brauchst keinerlei Vorkenntnisse — dieses Tutorial ist speziell für Anfänger gedacht. Installiere einfach Unity 6.0 LTS (oder eine aktuelle Version mit 2D-Unterstützung) und mach mit.
Wir gehen jeden Schritt ruhig und verständlich durch, mit Erklärungen und Beispielen. Wenn du gerade mit der Spieleentwicklung in Unity startest, ist dieses Tutorial genau richtig für dich.
Wir beginnen damit, ein neues Unity 2D-Projekt zu erstellen und das Template 2D (Built-in Core) auszuwählen. Damit erhalten wir eine saubere Szene mit eingebauter Unterstützung für Sprites, Collider und 2D-Physik.
💡Tipp: Du kannst dein Projekt SpaceShooter
nennen oder
dir einen anderen spaßigen Namen ausdenken – ganz wie du willst.
Jetzt bringen wir unsere Grafiken in Unity.
Lade die Bilddatei space-sprites.png
herunter — sie
enthält alle Grafiken, die wir brauchen: Gegner, Spielerschiff,
Projektil und mehr.
Öffne dein Unity-Projekt und importiere die Datei:
Nach dem Import wähle space-sprites.png im Assets-Fenster aus. Im Inspector-Panel achte darauf:
Sprite (2D and UI)
gesetzt
Multiple
💡Tipp: “Multiple” bedeutet, dass das Bild mehrere Sprites enthält – wie ein Blatt mit verschiedenen Figuren.
Unity sollte das Bild automatisch in einzelne Sprites aufteilen. Falls nicht, klicke auf Open Sprite Editor und verwende die Schaltfläche Slice mit Type: Automatic. Danach klicke auf Apply.
💡Tipp: Wenn das automatische Schneiden nicht funktioniert, kannst du auf Gitter-basiertes Schneiden umstellen oder manuell zuschneiden. Vergiss nicht, vor dem Schließen des Editors auf Apply zu klicken.
Jetzt bauen wir das Schiff, das wir steuern werden. In diesem Spiel benutzen wir keine Tastatur — sondern die Maus. Das Schiff soll zu dem Punkt fliegen, auf den wir klicken.
Ziehe zunächst das blaue Schiff-Sprite in die Szene. Unity erstellt
ein neues GameObject. Benenne es in Player
um und setze
den Tag auf Player.
Passe die Größe des Schiffs mit dem Rect Tool direkt in der Szene an oder ändere die Scale-Werte im Inspector, damit es genau richtig aussieht.
Jetzt fügen wir Physik hinzu. Wähle Player
aus, klicke
auf Add Component und füge Folgendes hinzu:
In den Rigidbody 2D-Einstellungen:
0
setzenInterpolate
setzen
Erstelle als Nächstes ein neues Skript mit dem Namen
PlayerMove und hänge es an das
Player
-Objekt.
Tipp: Rechtsklicke im Assets-Ordner →
Create → C# Script, gib ihm den Namen PlayerMove
und doppelklicke dann auf das Skript, um es in Visual Studio oder
einem anderen Editor zu öffnen.
In diesem Skript erfassen wir, wo der Spieler mit der Maus geklickt hat, wandeln diese Position von Bildschirmkoordinaten in Welt- (Szene-)Koordinaten um und lassen dann das Schiff zu diesem Punkt fliegen. Ganz einfach — das Schiff fliegt immer dorthin, wo du klickst.
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
// Der Punkt, zu dem das Schiff fliegen soll (angeklickt vom Spieler)
Vector3 clickPos;
// Der Richtungsvektor zum Zielpunkt
Vector3 move;
// Geschwindigkeit des Schiffs
public float speed = 1f;
// Referenz auf das Rigidbody2D
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
// Zu Beginn des Spiels setzen wir das Ziel auf die aktuelle Position,
// damit das Schiff nicht sofort losfliegt
clickPos = transform.position;
}
void Update()
{
// In jedem Frame prüfen wir, ob die linke Maustaste gedrückt ist,
// und aktualisieren dann den Zielpunkt
if (Input.GetMouseButton(0))
{
// Mausposition von Bildschirm- in Weltkoordinaten umrechnen
clickPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
// Richtung vom aktuellen Punkt zum Ziel berechnen
move = clickPos - transform.position;
}
void FixedUpdate()
{
// In jedem Physik-Frame die Geschwindigkeit setzen,
// damit das Schiff zum Ziel fliegt
rb.linearVelocity = new Vector2(move.x, move.y) * speed;
}
}
Speichere das Skript und kehre zu Unity zurück. Setze im Inspector den
Wert Speed
auf 1
. Drücke auf Play und teste
— das Schiff sollte sich nun zur Klickposition bewegen.
💡Tipp: Die Mausposition wird in Bildschirmkoordinaten (Pixel)
angegeben. Um sie in eine Szene-Position umzuwandeln, verwende
Camera.ScreenToWorldPoint
. Das Ergebnis ist ein Punkt in
der Welt — beachte: der Z-Wert
entspricht der Z-Position der Kamera. Für 2D reicht das meist — wir
brauchen nur X und Y.
Jetzt geben wir unserem Schiff etwas zum Schießen — wir fügen einen Laser hinzu.
Ziehe das orangefarbene Laser-Sprite in die Szene. Unity erstellt ein
neues GameObject. Benenne es in Laser
um. Setze im
Inspector den Order in Layer auf
-10
, damit der Laser hinter dem Schiff gezeichnet wird.
Passe die Größe bei Bedarf an – er sollte klein und klar aussehen.
Füge dem Objekt Laser
folgende Komponenten und
Einstellungen hinzu:
0
Interpolate
Erstelle nun ein neues MonoBehaviour-Skript mit dem
Namen LaserShot
. Dieses Skript wird den Laser direkt nach
dem Erstellen nach oben schieben und ihn zerstören, sobald er den
Bildschirm verlässt.
using UnityEngine;
public class LaserShot : MonoBehaviour
{
// Referenz auf das Rigidbody2D, um Kraft anzuwenden
Rigidbody2D rb;
// Die Kraft, mit der der Laser nach oben fliegt
public float force = 5f;
void Start()
{
rb = GetComponent<Rigidbody2D>();
// Einen Vektor erstellen, der nach oben zeigt (Y) mit der gegebenen Kraft
Vector3 direction = new Vector3(0, force, 0);
// Sofort einen Impuls anwenden, damit der Laser nach oben schießt
rb.AddForce(direction, ForceMode2D.Impulse);
}
void OnBecameInvisible()
{
// Sobald der Laser außerhalb des Kamerabereichs ist, wird er zerstört
Destroy(gameObject);
}
}
Hänge dieses Skript an das Laser
-Objekt und setze den
Force
-Wert z. B. auf 5
.
Ziehe das Laser
-GameObject ins
Assets-Fenster, um ein Prefab zu erstellen. Unity
erstellt es automatisch. Danach kannst du den Laser aus der Szene
löschen — wir werden ihn später per Skript erzeugen.
Der Laser kann jetzt fliegen — jetzt bringen wir dem Schiff das Schießen bei.
Wir verwenden ein neues Skript, das jedes Mal einen Laser erzeugt, wenn der Spieler die rechte Maustaste drückt. Um zu vermeiden, dass zu viele Laser gleichzeitig erscheinen, fügen wir eine kurze Verzögerung per Coroutine hinzu.
Erstelle ein neues MonoBehaviour Skript mit dem Namen
PlayerShoot
. Es wird so aussehen:
using UnityEngine;
using System.Collections;
public class PlayerShoot : MonoBehaviour
{
// Das Laser-Prefab, das beim Schießen erzeugt wird
public GameObject laser;
// Verzögerung zwischen Schüssen (Nachladezeit)
public float delayTime = 0.5f;
// Flag: dürfen wir gerade schießen?
bool canShoot = true;
void Update()
{
// In jedem Frame prüfen: wird die rechte Maustaste gedrückt
// und dürfen wir schießen (Nachladen abgeschlossen)?
if (canShoot && Input.GetMouseButton(1))
{
// Schießen bis zum Ende der Nachladezeit blockieren
canShoot = false;
// Laser (Kopie des Prefabs) an der Position des Spielers erzeugen
Instantiate(laser, transform.position, transform.rotation);
// Timer für die Nachladezeit starten
StartCoroutine(NoFire());
}
}
// Coroutine — wartet delayTime Sekunden, dann darf wieder geschossen werden
IEnumerator NoFire()
{
yield return new WaitForSeconds(delayTime);
canShoot = true;
}
}
Hänge das PlayerShoot
-Skript an das Spielerobjekt. Ziehe
das Laser
-Prefab in das Feld Laser.
Setze Delay Time auf 0.5
.
Klicke auf Play und probiere es aus — dein Schiff sollte jetzt schießen, wenn du rechts klickst!
Jetzt fügen wir etwas Gefahr hinzu. Wir verwenden eine kleine Minen-Gegnerin, die nach unten in Richtung Spieler treibt.
Ziehe das Minen-Sprite in die Szene. Unity erstellt ein neues
GameObject — benenne es in Mine
um. Setze
Order in Layer auf -5
(zwischen Schiff
und Laser). Passe die Größe bei Bedarf an.
Füge der Mine folgende Komponenten und Einstellungen hinzu:
0
Interpolate
Erstelle einen neuen Tag namens Enemy
und weise ihn der
Mine zu.
Erstelle nun ein neues MonoBehaviour-Skript mit dem
Namen MineMove
. Es wird die Mine nach unten bewegen, sie
zerstören, wenn sie den Bildschirm verlässt, und die Szene neu
starten, falls sie mit dem Spieler kollidiert.
using UnityEngine;
using System.Collections;
// Diese Bibliothek wird benötigt, um Szenen zu verwalten (neu zu laden)
using UnityEngine.SceneManagement;
public class MineMove : MonoBehaviour
{
// Geschwindigkeit, mit der sich die Mine bewegt
public float speed = 1f;
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
// Erstelle einen Vektor, der nach unten zeigt (Y-Achse)
Vector3 move = new Vector3(0, -1, 0);
// Setze die lineare Geschwindigkeit, damit die Mine nach unten fliegt
rb.linearVelocity = move * speed;
}
void OnBecameInvisible()
{
// Zerstöre die Mine, wenn sie den Bildschirm verlässt
Destroy(gameObject);
}
void OnCollisionEnter2D(Collision2D collision)
{
// Prüfen: hat die Mine etwas mit dem Tag "Player" getroffen?
if (collision.gameObject.tag == "Player")
{
// Lade die aktuelle Szene neu
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
}
Hänge das Skript an das Mine
-Objekt. Setze
Speed auf 1
. Ziehe dann die Mine in das
Assets-Fenster, um ein Prefab zu erstellen. Danach
kannst du sie aus der Szene löschen — wir erzeugen sie später per
Skript.
Jetzt automatisieren wir die Gegnerwellen. Wir richten einen Spawner ein, der neue Minen an zufälligen Positionen erzeugt.
Gehe zu GameObject → Create Empty. Unity erstellt ein
neues GameObject in der Szene. Benenne es in
MineSpawner
um. Du kannst ihm ein benutzerdefiniertes
Icon zuweisen, um es in der Szene leichter zu finden.
Verschiebe den MineSpawner
in die obere linke Ecke des
sichtbaren Bildschirmbereichs. Achte darauf, dass seine
Z-Position auf 0
gesetzt ist, da es sich
um ein 2D-Spiel handelt.
Wähle MineSpawner
aus, drücke
Strg + D (oder Rechtsklick → Duplizieren). Benenne
das neue Objekt in RightPosition
um und mache es zu einem
Child von MineSpawner. Verschiebe es in die obere
rechte Ecke des Bildschirms. Setze auch hier die Z-Position auf
0
.
Erstelle nun ein neues MonoBehaviour-Skript mit dem
Namen ObjectSpawner
. Es wird eine zufällige X-Position
zwischen den beiden Punkten auswählen und dort Minen mit
Zeitverzögerung erzeugen.
using UnityEngine;
using System.Collections;
public class ObjectSpawner : MonoBehaviour
{
// Rechter Punkt für zufällige X-Position
public Transform RightPosition;
// Verzögerung zwischen Spawns
public float spawnDelay = 5f;
// Objekt, das gespawnt wird
public GameObject Item;
void Start()
{
// Funktion regelmäßig aufrufen
InvokeRepeating("Spawn", spawnDelay, spawnDelay);
}
void Spawn()
{
// Zufällige X-Position zwischen Spawner und rechtem Punkt wählen
Vector3 spawnPos = new Vector3(
Random.Range(transform.position.x, RightPosition.position.x),
transform.position.y,
0);
// Objekt an der berechneten Position erzeugen
Instantiate(Item, spawnPos, transform.rotation);
}
}
Hänge dieses Skript an das MineSpawner
-Objekt. Ziehe
RightPosition
in das Feld
Right Position und das Mine
-Prefab in
das Feld Item. Setze Spawn Delay auf
5
.
Klicke auf Play — nun erscheinen Minen automatisch an zufälligen Positionen oben auf dem Bildschirm.
Momentan fliegen die Laser einfach durch die Minen hindurch — ohne Auswirkungen. Das ändern wir jetzt, indem wir den Minen Lebenspunkte geben und den Lasern Schaden zuweisen.
Erstelle ein neues MonoBehaviour-Skript mit dem Namen
HpController
. Es speichert die Lebenspunkte und zerstört
das Objekt, wenn diese auf null fallen.
using UnityEngine;
public class HpController : MonoBehaviour
{
// Anzahl der Lebenspunkte (HP)
public int hp = 3;
// Methode, die die Gesundheit um den erhaltenen Schaden reduziert
void MakeDamage(int damage)
{
// Ziehe den übergebenen Schaden von den aktuellen Lebenspunkten ab
hp -= damage;
// Wenn die Gesundheit auf null oder darunter fällt — zerstöre dieses Objekt
if (hp <= 0)
{
Destroy(gameObject);
}
}
}
Wähle das Mine
-Prefab im Assets-Fenster aus und füge das
HpController
-Skript hinzu. Setze hp auf
3
.
Öffne jetzt das LaserShot
-Skript. Wir prüfen dort die
Kollisionen und schicken Schaden an den Gegner.
using UnityEngine;
public class LaserShot : MonoBehaviour
{
// Referenz auf Rigidbody2D, um Kraft anzuwenden
Rigidbody2D rb;
// Die Kraft, mit der der Laser nach oben geschossen wird
public float force = 10f;
// Schaden, den der Laser Gegnern zufügt
public int damage = 1;
void Start()
{
rb = GetComponent<Rigidbody2D>();
// Erstelle einen Vektor, der nach oben zeigt, mit der angegebenen Kraft
Vector3 direction = new Vector3(0, force, 0);
// Wende sofort einen Impuls an, damit der Laser nach oben fliegt
rb.AddForce(direction, ForceMode2D.Impulse);
}
void OnBecameInvisible()
{
// Zerstöre den Laser, wenn er den Bildschirm verlässt
Destroy(gameObject);
}
void OnTriggerEnter2D(Collider2D other)
{
// Prüfen, ob der Laser ein Objekt mit dem Tag "Enemy" getroffen hat
if (other.gameObject.tag == "Enemy")
{
// Sende dem Gegner die Nachricht "MakeDamage" und übergebe den Schaden.
// Falls das Objekt diese Methode nicht hat, passiert nichts Schlimmes.
other.gameObject.SendMessage("MakeDamage", damage, SendMessageOptions.DontRequireReceiver);
// Zerstöre den Laser nach dem Treffer
Destroy(gameObject);
}
}
}
Wähle das Laser
-Prefab aus und setze den
Damage-Wert im Inspector auf 1
.
Klicke auf Play und teste die Szene. Minen sollten nun drei Treffer benötigen, um zerstört zu werden.
Fügen wir nun einen Gegner hinzu, der zurückschießen kann.
Ziehe das Sprite des feindlichen Schiffs in die Szene. Unity erstellt
dabei automatisch ein neues Objekt. Benenne es um in
Enemy-1
. Ändere den Tag auf Enemy
. Setze
Order in Layer auf -5
, damit der Gegner
über den Lasern angezeigt wird. Passe die Größe bei Bedarf an.
Füge dem Objekt folgende Komponenten und Einstellungen hinzu:
0
Interpolate
Füge nun das Skript HpController
zum feindlichen Schiff
hinzu und stelle HP auf 1
ein. Danach
füge dasselbe Skript MineMove
hinzu und setze
speed
auf 1
(oder einen anderen Wert nach deinem Geschmack), damit die Untertasse
ruhig nach unten fliegt.
Ziehe anschließend Enemy-1
in das
Assets-Fenster, um ein neues Prefab für den Gegner zu
erstellen. Danach kannst du Enemy-1
aus der Szene löschen — es bleibt im Projekt als Prefab erhalten.
HpController
, MineMove
.
Jetzt geben wir diesem Gegner eine Rakete. Ziehe das Raketen-Sprite in
die Szene und benenne es in Rocket
um. Setze
Order in Layer auf -10
. Füge einen
Box Collider 2D hinzu und aktiviere
Is Trigger. Füge ein
Rigidbody 2D hinzu mit
Gravity Scale = 0 und
Interpolate = Interpolate.
using UnityEngine;
public class EnemyBullet : MonoBehaviour
{
// Referenz auf das Spieler-Objekt
GameObject player;
// Referenz auf Rigidbody2D, um Kraft anzuwenden
Rigidbody2D rb;
// Impulskraft, mit der die Rakete gestartet wird
public float force = 3f;
// Schaden, den die Rakete bei einem Treffer verursacht
public int damage = 1;
void Start()
{
rb = GetComponent<Rigidbody2D>();
// Finde den Spieler in der Szene anhand des Tags "Player"
player = GameObject.FindWithTag("Player");
if (player != null)
{
// Berechne den Richtungsvektor von der Rakete zum Spieler
Vector3 dir = player.transform.position - transform.position;
// Drehe die Rakete in Richtung des Spielers
transform.up = dir;
// Wende einen Impuls in die lokale "Up"-Richtung der Rakete an
rb.AddRelativeForce(transform.up * force, ForceMode2D.Impulse);
}
else
{
// Falls kein Spieler vorhanden ist, zerstöre die Rakete
Destroy(gameObject);
}
}
void OnTriggerEnter2D(Collider2D other)
{
// Prüfen, ob die Rakete mit dem Spieler kollidiert ist
if (other.gameObject.tag == "Player")
{
// Dem Spieler Schaden zufügen
other.gameObject.SendMessage("MakeDamage", damage, SendMessageOptions.DontRequireReceiver);
// Die Rakete nach dem Treffer zerstören
Destroy(gameObject);
}
}
void OnBecameInvisible()
{
// Die Rakete zerstören, wenn sie den Bildschirm verlässt
Destroy(gameObject);
}
}
Füge das EnemyBullet
-Skript dem
Rocket
-Objekt hinzu. Setze Force auf
3
und Damage auf 1
.
Erstelle ein Prefab, indem du die Rakete ins Assets-Fenster ziehst.
Danach kannst du sie aus der Szene löschen.
Jetzt geben wir dem feindlichen Schiff etwas Feuerkraft. Wir fügen ein Skript hinzu, das regelmäßig eine Rakete erzeugt — alles Weitere übernimmt dann die Rakete selbst.
Erstelle ein neues MonoBehaviour-Skript und nenne es
EnemyShoot
. Dieses Skript ist einfach aufgebaut und lässt
den Gegner in regelmäßigen Abständen Raketen spawnen, solange es einen
Spieler in der Szene gibt.
using UnityEngine;
using System.Collections;
public class EnemyShoot : MonoBehaviour
{
// Das Prefab der Rakete, die gespawnt wird
public GameObject bullet;
// Verzögerung zwischen Schüssen (in Sekunden)
public float fireDelay = 2f;
// Referenz auf den Spieler in der Szene
GameObject player;
// Flag: darf der Gegner gerade schießen?
bool canShoot = true;
void Start()
{
// Finde den Spieler anhand des Tags "Player"
player = GameObject.FindWithTag("Player");
}
void Update()
{
// Wenn Schießen erlaubt ist und der Spieler existiert
if (canShoot && player != null)
{
// Blockiere weiteres Schießen bis nach der Wartezeit
canShoot = false;
// Erzeuge eine Rakete an der Position des Gegners
Instantiate(bullet, transform.position, Quaternion.identity);
// Starte Coroutine, um bis zum nächsten Schuss zu warten
StartCoroutine(firePause());
}
}
IEnumerator firePause()
{
// Warte fireDelay Sekunden
yield return new WaitForSeconds(fireDelay);
// Erlaube wieder zu schießen
canShoot = true;
}
}
Wähle das Enemy-1
-Prefab im Assets-Fenster aus. Füge das
Skript EnemyShoot
hinzu. Ziehe das
Rocket
-Prefab in das Feld Bullet. Setze
Fire Delay auf 2
.
Unser Enemy-1
-Prefab ist fertig. Jetzt lassen wir es —
genau wie die Minen — in der Szene erscheinen. Statt einen zweiten
Spawner zu bauen, verbessern wir einfach den bestehenden und erlauben
ihm, zufällig zwischen mehreren Objekten zu wählen.
Öffne das Skript ObjectSpawner
und passe es so an, dass
es ein Array von Prefabs verwendet:
using UnityEngine;
public class ObjectSpawner : MonoBehaviour
{
// Rechte Grenze für das Spawnen (links ist das Objekt, an dem dieses Skript hängt)
public Transform RightPosition;
// Verzögerung zwischen den Spawns (Sekunden)
public float spawnDelay;
// Array von Prefabs, aus dem zufällig ausgewählt wird
public GameObject[] Item;
void Start()
{
// Ruft die Funktion Spawn wiederholt mit der angegebenen Verzögerung auf
InvokeRepeating("Spawn", spawnDelay, spawnDelay);
}
void Spawn()
{
// Wählt einen zufälligen Punkt zwischen unserer Position und der rechten Grenze auf der X-Achse
Vector3 spawnPos = new Vector3(
Random.Range(transform.position.x, RightPosition.position.x),
transform.position.y,
0
);
// Wählt zufällig ein Prefab aus dem Array
int i = Random.Range(0, Item.Length);
// Erzeugt das ausgewählte Objekt an der berechneten Position
Instantiate(Item[i], spawnPos, transform.rotation);
}
}
Wähle in der Szene das Objekt MineSpawner
aus und öffne
die aktualisierte Item-Liste. Füge sowohl das
Mine
- als auch das Enemy-1
-Prefab hinzu.
Unity passt die Listengröße automatisch an.
Unser Spieler hat derzeit keine sichtbare Gesundheit. Wir fügen eine einfache Benutzeroberfläche hinzu, um die aktuellen HP anzuzeigen. Dazu erstellen wir eine horizontale Lebensleiste mit Unitys eingebautem UI-System.
Gehe zu GameObject → UI → Image. Dadurch wird ein
neues Canvas
mit einem Image
-Objekt
erstellt. Benenne das Image in HealthBar
um.
Wähle das Canvas
aus. Im Inspector unter
Canvas Scaler stelle
UI Scale Mode auf
Scale With Screen Size
.
Doppelklicke nun im Hierarchy-Fenster auf Canvas
— die
Szene zoomt zur UI. Wähle HealthBar
aus und verwende das
Rect Tool, um es in die Form einer Leiste zu bringen.
Du kannst sie platzieren, wo es am besten zum Layout passt.
Mit ausgewähltem HealthBar
stelle folgendes ein:
Background
Filled
Horizontal
Left
Hinweis: Fill Method und Origin könnten automatisch gesetzt werden, sobald du Filled auswählst. Du kannst später damit experimentieren, aber für jetzt passt es so.
Jetzt verbinden wir den Gesundheitsindikator mit dem Gameplay. Wir
schreiben ein Skript, das den erlittenen Schaden des Spielers verfolgt
und die Healthbar aktualisiert. Die Image-Komponente
auf dem HealthBar
-Objekt hat die Eigenschaft
fillAmount
, die steuert, wie voll der Sprite angezeigt
wird. Indem wir den Prozentsatz der verbleibenden Lebenspunkte
berechnen, passen wir fillAmount
an, um den aktuellen
HP-Stand auf unserer Anzeige darzustellen.
Erstelle ein neues MonoBehaviour-Skript namens
PlayerHp
:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class PlayerHp : MonoBehaviour
{
// Referenz auf das HealthBar-UI-Objekt (ein Image)
public GameObject HealthBar;
// Referenz auf die Image-Komponente, um fillAmount zu ändern
Image img;
// Aktuelle Lebenspunkte
public int hp;
// Maximale Lebenspunkte (für die Normalisierung des Balkens)
float maxHp;
void Start()
{
// Holt die Image-Komponente vom HealthBar-Objekt
img = HealthBar.GetComponent<Image>();
// Speichert den Wert der maximalen Lebenspunkte
maxHp = hp;
// Setzt die anfängliche Füllung des HealthBars
img.fillAmount = hp / maxHp;
}
// Methode, um Schaden zu nehmen
void MakeDamage(int damage)
{
// Zieht den Schaden von den aktuellen Lebenspunkten ab
hp -= damage;
// Wenn die Lebenspunkte auf 0 oder darunter fallen, wird die Szene neu geladen
if (hp <= 0)
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
// Aktualisiert die Füllmenge des HealthBars
img.fillAmount = hp / maxHp;
}
}
Gehe nun zur Szene und wähle dein Player-Objekt aus.
Füge das Skript PlayerHp
hinzu. Ziehe das
HealthBar
-Objekt (aus dem Canvas) in das Feld
Health Bar. Setze den HP-Wert auf
10
.
Beginnen wir damit, den Hintergrund unserer Szene in ein tiefes
Weltraum-Schwarz zu tauchen. Wähle die Main Camera in
der Hierarchie. Im Inspector gehe zum Bereich
Camera und setze die
Background-Farbe auf black
.
Für einen schönen Weltraum-Effekt verwenden wir Unitys eingebautes Partikelsystem, um sich bewegende Sterne zu simulieren.
Stars
um.10
und die
X-Rotation auf 90
.
0.2
(oder
nach Wunsch).
Box
.15
, damit das
Sternfeld breit genug ist.
-100
,
damit die Sterne weit im Hintergrund angezeigt werden.
Geben wir der feindlichen Rakete einen passenden Sound. Immer wenn eine Rakete gespawnt wird, spielen wir einen kurzen Klang über Unitys integriertes Audiosystem ab.
Die Soundeffekte dieses Tutorials kannst du hier herunterladen:
Importiere die heruntergeladenen Audiodateien in Unity.
Im Skript EnemyBullet
verwenden wir die Methode
PlayClipAtPoint
, um Sounds abzuspielen.
Damit wird die gewünschte Audiodatei genau beim Start der Rakete abgespielt. Unity erstellt dafür ein temporäres Audio-Objekt in der Szene, das den Sound abspielt und anschließend automatisch verschwindet.
Hier ist das vollständige, aktualisierte
EnemyBullet
-Skript mit Sound-Unterstützung:
using UnityEngine;
public class EnemyBullet : MonoBehaviour
{
// Referenz auf den Spieler (per Tag "Player" gefunden)
GameObject player;
// Referenz auf Rigidbody2D für die Bewegung
Rigidbody2D rb;
// Kraft, die die Kugel antreibt
public float force = 3f;
// Schaden, den die Kugel verursacht
public int damage = 1;
// Sound, der beim Schuss abgespielt wird
public AudioClip BulletSound;
void Start()
{
// Holt das Rigidbody2D-Component
rb = GetComponent<Rigidbody2D>();
// Findet den Spieler über den Tag
player = GameObject.FindWithTag("Player");
// Wenn Spieler gefunden wurde
if (player != null)
{
// Berechnet Richtung zum Spieler
Vector3 dir = player.transform.position - transform.position;
// Dreht die Kugel in Richtung Spieler
transform.up = dir;
// Wendet Kraft an, damit die Kugel losfliegt
rb.AddRelativeForce(transform.up * force, ForceMode2D.Impulse);
// Spielt den Schuss-Sound an der Position der Kugel ab
AudioSource.PlayClipAtPoint(BulletSound, transform.position);
}
else
{
// Wenn kein Spieler gefunden, zerstöre die Kugel
Destroy(gameObject);
}
}
void OnTriggerEnter2D(Collider2D other)
{
// Wenn die Kugel den Spieler trifft
if (other.gameObject.tag == "Player")
{
// Schickt Nachricht an Spieler, um Schaden zuzufügen
other.gameObject.SendMessage("MakeDamage", damage, SendMessageOptions.DontRequireReceiver);
// Zerstört die Kugel
Destroy(gameObject);
}
}
void OnBecameInvisible()
{
// Zerstört die Kugel, wenn sie außerhalb des Bildschirms ist
Destroy(gameObject);
}
}
Wähle nun das Rocket-Prefab aus. Weise im
EnemyBullet
-Skript das Feld
Bullet Sound der Audiodatei
LaserSound
zu.
💡 Du kannst auch deinen eigenen Sound verwenden — importiere einfach
eine
.wav
-Datei und ziehe sie in das
AudioClip-Feld.
Genauso wie bei den Raketen der Gegner möchten wir auch beim
Laserschuss des Spielers einen Ton hinzufügen. Öffne das
LaserShot
-Skript und aktualisiere es wie folgt:
using UnityEngine;
public class LaserShot : MonoBehaviour
{
// Referenz auf Rigidbody2D für Physik
Rigidbody2D rb;
// Impulsstärke, mit der der Laser nach oben geschossen wird
public float force = 10f;
// Wie viel Schaden der Laser verursacht
public int damage = 1;
// AudioClip für das Abspielen des Schuss-Sounds
public AudioClip LaserSound;
void Start()
{
// Rigidbody2D-Komponente von diesem Objekt holen
rb = GetComponent<Rigidbody2D>();
// Einen Vektor nach oben (Y-Achse) erstellen
Vector3 direction = new Vector3(0, force, 0);
// Impulskraft hinzufügen, um den Laser zu starten
rb.AddForce(direction, ForceMode2D.Impulse);
// Schuss-Sound an dieser Position abspielen
AudioSource.PlayClipAtPoint(LaserSound, transform.position);
}
void OnBecameInvisible()
{
// Laser zerstören, wenn er den Bildschirm verlässt
Destroy(gameObject);
}
void OnTriggerEnter2D(Collider2D other)
{
// Prüfen, ob wir etwas mit dem Tag "Enemy" getroffen haben
if (other.gameObject.tag == "Enemy")
{
// Dem Gegner mitteilen, dass er Schaden nehmen soll
other.gameObject.SendMessage("MakeDamage", damage, SendMessageOptions.DontRequireReceiver);
// Laser nach dem Treffer zerstören
Destroy(gameObject);
}
}
}
Nachdem du das Skript aktualisiert hast, öffne das
Laser-Prefab im Assets-Fenster und weise die Datei
LaserSound.wav
dem neuen Feld
Laser Sound zu.
💡 Du kannst auch deine eigenen Soundeffekte verwenden — ziehe eine
beliebige
.wav
-Datei in den Ordner Assets/sound
und
weise sie zu.
Wenn Minen oder Gegner zerstört werden, wollen wir ein kurzes
Explosionsgeräusch abspielen. Dazu erweitern wir das Skript
HpController
um ein Audiofeld und spielen den Ton ab,
wenn die Lebenspunkte auf null fallen.
using UnityEngine;
public class HpController : MonoBehaviour
{
// Lebenspunkte des Objekts
public int hp = 3;
// Soundeffekt für die Explosion
public AudioClip ExplosionsSound;
void MakeDamage(int damage)
{
// Schaden von den Lebenspunkten abziehen
hp -= damage;
// Wenn die Lebenspunkte aufgebraucht sind
if (hp <= 0)
{
// Explosionston abspielen
AudioSource.PlayClipAtPoint(ExplosionsSound, transform.position);
// Objekt zerstören
Destroy(gameObject);
}
}
}
Wähle die Prefabs Mine und
Enemy-1 im Assets
-Fenster aus. Weise im
HpController das Feld
Explosions Sound mit der Datei
Boom.wav
zu.
Das war’s! Jetzt wird bei jeder Zerstörung ein passendes Explosionsgeräusch abgespielt.
💡 Du kannst natürlich auch eigene Sounds verwenden — einfach ins
Assets/sound
-Verzeichnis ziehen und zuweisen.
Es fehlt noch ein Partikeleffekt, wenn ein Gegner (z. B. Mine oder
Enemy-1) zerstört wird. Erstelle ein neues
Particle System und benenne es
KiavoBoom
. Setze Position und
Rotation auf 0
. Nimm im Inspector
folgende Einstellungen vor:
Öffne das Emission-Modul und füge einen
Burst bei 0.0
mit 30
Partikeln
hinzu.
Im Shape-Modul wähle Circle
und setze
den Radius
auf 0.1
.
Aktiviere Color over Lifetime. Stelle im Farbeditor
Alpha am Ende auf 0
und wähle passende Farben.
Im Renderer-Modul stelle
Order in Layer auf 10
.
Stelle im Abschnitt Main den Parameter
Stop Action auf Destroy
. Das bedeutet,
dass sich das Objekt nach Ende des Effekts automatisch selbst
entfernt.
Erstelle anschließend ein Prefab aus KiavoBoom
und
entferne es aus der Szene — es bleibt im Projekt für spätere Spawns
erhalten.
Später kannst du die Explosion noch bunter oder dramatischer gestalten — das hier ist nur der erste Effekt.
KiavoBoom
ist einsatzbereit — ein kleiner
Partikelausbruch bei der Zerstörung. Einfach, schnell und visuell
schön.
Jetzt haben wir ein Explosions-Prefab. Dieses soll abgespielt werden,
sobald ein Gegner (z. B. Mine oder Enemy-1) zerstört wird. Öffne das
Skript HpController
und ändere es wie folgt:
using UnityEngine;
public class HpController : MonoBehaviour
{
// Anzahl der Lebenspunkte
public int hp = 3;
// Prefab für Explosionseffekt
public GameObject Explosion;
// Explosionsgeräusch
public AudioClip ExplosionsSound;
void MakeDamage(int damage)
{
// Schaden von den Lebenspunkten abziehen
hp -= damage;
// Wenn keine Lebenspunkte mehr übrig sind
if (hp <= 0)
{
// Explosionssound abspielen
AudioSource.PlayClipAtPoint(ExplosionsSound, transform.position);
// Explosionseffekt erzeugen
Instantiate(Explosion, transform.position, Quaternion.identity);
// Objekt zerstören
Destroy(gameObject);
}
}
}
Wähle die Prefabs Mine und
Enemy-1 aus. Weise im HpController
dein
Explosions-Prefab (z. B. KiavoBoom
) dem Feld
Explosion zu.
KiavoBoom
ist jetzt im
HpController
der Gegner verknüpft. Beim Zerstören
verschwinden sie mit Ton und Partikeln.
Unser Spiel ist jetzt komplett — mit Bewegung, Gegnern, Schüssen, Ton und Benutzeroberfläche. Dieses Tutorial zeigt dir, wie du mit einfachen Mitteln ein funktionierendes 2D-Space-Shooter-Spiel baust.
Natürlich kannst du noch viel mehr hinzufügen: Explosionen, Effekte, Gegnerwellen, Punkte, Leben, Menüs, Bosskämpfe, Musik… oder fliegende Hühner und Weltraum-Tee ☕🛸
Aber unser Ziel war es, dir ein klares, leicht verständliches Fundament zu geben — und das hast du jetzt.
💡 Experimentiere weiter, hab Spaß und baue dein eigenes Spiel darauf auf!