奖励
Coddy Unity 塔防游戏 课程的第 13 课,共 25 课。
防御塔击败的每个敌人都会提供 reward。Enemy 会像报告敌人到达基地那样报告击杀事件,使用静态事件 Killed,而 GameManager 会监听该事件并增加金钱。
一次击杀只能获得一次奖励。Destroy 不会立即移除对象:它会等到当前帧结束时才移除,在此之前对象仍在游戏中。两发子弹可能在同一帧命中,第二发会击中一个生命值为 0、但仍然存在的敌人。如果 TakeDamage 每次发现生命值为 0 或更低时都报告击杀,那么第二发子弹就会再次发放奖励。用飞镖玩气球游戏时也会遇到同样的问题,可以用一个 bool 来避免:
public void Pop()
{
if (popped)
{
return;
}
popped = true;
Popped?.Invoke(this);
Destroy(gameObject);
}敌人不需要额外的 bool,因为它的生命值已经能说明它是否死亡:如果 TakeDamage 发现生命值为 0 或更低,就没有什么可做了。
挑战
中等每次击杀都会获得敌人的奖励。
- 在
Enemy中,添加public static event Action<Enemy> Killed;,并在敌人被销毁前,在TakeDamage中触发该事件。 - 让
TakeDamage以if (health <= 0) return;开头,这样每次击杀只会获得一次奖励。 - 在
GameManager中,添加public void Earn(int amount)(添加金额并显示),然后订阅Enemy.Killed,以获得enemy.data.reward。
按下“开始”:炮塔运作时,金钱会增加。然后点击“检查”。
亲手试试
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);
}
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
Unity 塔防游戏中的所有课
自己练习: Unity 在线编辑器