Belohnungen
Lektion 13 von 25 im Kurs Unity-Spiel: Tower Defense von Coddy.
Jeder Gegner, den ein Turm zur Strecke bringt, zahlt seine reward. Der Enemy meldet den Abschuss so, wie er das Erreichen der Basis meldet: mit einem statischen Event, Killed, und der GameManager hört darauf und fügt das Geld hinzu.
Ein Abschuss darf nur einmal bezahlt werden. Destroy entfernt ein Objekt nicht sofort: Das geschieht erst am Ende des Frames, und bis dahin ist es noch im Spiel. Zwei Schüsse können im selben Frame treffen, und der zweite trifft einen Gegner mit 0 Lebenspunkten, der noch da ist. Wenn TakeDamage jedes Mal einen Abschuss meldet, wenn die Lebenspunkte 0 oder darunter betragen, wird der zweite Schuss erneut bezahlt. Bei einem Ballonspiel mit Dartpfeilen gibt es dieselbe Falle, und ein bool verhindert sie:
public void Pop()
{
if (popped)
{
return;
}
popped = true;
Popped?.Invoke(this);
Destroy(gameObject);
}Der Enemy braucht kein zusätzliches bool, da seine Lebenspunkte bereits anzeigen, ob er tot ist: Bei einem TakeDamage-Aufruf, der feststellt, dass die Lebenspunkte 0 oder darunter liegen, gibt es nichts mehr zu tun.
Aufgabe
MittelFür jeden besiegten Gegner erhältst du dessen Belohnung.
- Füge in
Enemypublic static event Action<Enemy> Killed;hinzu und löse das Ereignis inTakeDamagedirekt vor dem Zerstören des Gegners aus. - Beginne
TakeDamagemitif (health <= 0) return;, damit eine Tötung nur einmal belohnt wird. - Füge in
GameManagerpublic void Earn(int amount)hinzu (füge den Betrag hinzu und zeige ihn an) und abonniereEnemy.Killed, umenemy.data.rewardgutzuschreiben.
Drücke auf „Spielen“: Das Geld steigt, während die Türme arbeiten. Drücke dann auf „Prüfen“.
Probier es selbst
using System;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour, IDamageable
{
public static readonly List<Enemy> All = new List<Enemy>();
public static event Action<Enemy> ReachedBase;
public EnemyData data;
public Transform[] waypoints;
private int next = 1;
private int health;
void Awake()
{
health = data.maxHealth;
}
void OnEnable()
{
All.Add(this);
}
void OnDisable()
{
All.Remove(this);
}
void Update()
{
Vector3 target = waypoints[next].position;
transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
if (transform.position == target)
{
next++;
if (next == waypoints.Length)
{
ReachedBase?.Invoke(this);
Destroy(gameObject);
}
}
}
public void TakeDamage(int amount)
{
health -= amount;
if (health <= 0)
{
Destroy(gameObject);
}
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Unity-Spiel: Tower Defense
Übe selbstständig: Unity-Playground