Menu
CoddyTech

轻量版塔防

本课属于 Coddy Unity 学习旅程的“Unity 游戏架构”单元。第 61 课,共 64 课。

怪物沿着道路向你的基地行进,基地由一座塔防守。只要有怪物进入射程,塔就会向离它最近的怪物发射箭矢;每击败一个怪物,都会获得金币。按空格键可以用金币提升塔的等级:每升一级,塔的射程更远、射速更快或伤害更高。怪物到达基地后就会闯入。等级数据由设计师在资源中调整,无需修改代码。塔会发射大量箭矢,因此会从对象池中重复使用箭矢,而不是每次射击都创建并销毁一个箭矢。

编写两个脚本:TowerData,资源类型;以及 Tower。Creep、Bolt 和 CreepSpawner 已经准备好,塔的 Nearest 和 Show 也已准备好。

challenge icon

挑战

困难

完成防御塔;Nearest(range) 和 Show() 已准备就绪。

  1. TowerLevel:可序列化,包含公共属性 range、fireEvery、damage、cost。TowerData 保存 public List<TowerLevel> levels。
  2. 每隔 fireEvery 秒,如果 Nearest(range) 找到一个小怪,就从 ObjectPool<Bolt> 中取出一枚 bolt,放到防御塔的位置:bolt.Launch(creep, damage, pool.Release)。
  3. Creep.Killed 触发并发放 bounty 后,以及按下 Space 并花费下一等级的 cost 购买该等级后,都调用 Show(),并记录 Tower level 2。

按下“开始”并升级,然后“检查”。

亲手试试

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Pool;
using TMPro;

public class Tower : MonoBehaviour
{
    [SerializeField] private TowerData data;
    [SerializeField] private Bolt boltPrefab;
    [SerializeField] private TMP_Text infoText;

    private int level;
    private int gold;

    // 已就绪:返回射程内离塔最近的小怪,找不到则返回 null。
    Creep Nearest(float range)
    {
        Creep nearest = null;
        float best = Mathf.Infinity;
        foreach (Collider hit in Physics.OverlapSphere(transform.position, range))
        {
            if (hit.TryGetComponent(out Creep creep))
            {
                float distance = Vector3.Distance(transform.position, creep.transform.position);
                if (distance < best)
                {
                    best = distance;
                    nearest = creep;
                }
            }
        }
        return nearest;
    }

    // 已就绪:显示等级和金币,例如 Level 1, 0 gold。
    void Show()
    {
        infoText.text = "Level " + (level + 1) + ", " + gold + " gold";
    }
}

Unity 游戏架构中的所有课

自己练习: Unity 在线编辑器