Belohnungen
Lektion 10 von 18 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
Mittel- Erkläre in
Enemyein öffentliches statisches EreignisKilled(Action<Enemy>). Löse es mit dem Gegner aus, wenn TakeDamage dessen Gesundheit auf 0 oder darunter senkt, direkt bevor du ihn zerstörst. - Ein Kill wird nur einmal vergütet: Wenn TakeDamage bei einem Gegner aufgerufen wird, dessen Gesundheit bereits 0 oder darunter liegt, passiert nichts.
- Füge in
GameManagerpublic void Earn(int amount)hinzu. Die Methode addiert den Betrag zum Geld und zeigt den neuen Stand an. AbonniereEnemy.Killedneben ReachedBase und vergüte dierewarddes getöteten Gegners.
Drücke auf Play und beobachte, wie das Geld wächst, während die Türme arbeiten, und klicke 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.