轻量版塔防
本课属于 Coddy Unity 学习旅程的“Unity 游戏架构”单元。第 61 课,共 64 课。
怪物沿着道路向你的基地行进,基地由一座塔防守。只要有怪物进入射程,塔就会向离它最近的怪物发射箭矢;每击败一个怪物,都会获得金币。按空格键可以用金币提升塔的等级:每升一级,塔的射程更远、射速更快或伤害更高。怪物到达基地后就会闯入。等级数据由设计师在资源中调整,无需修改代码。塔会发射大量箭矢,因此会从对象池中重复使用箭矢,而不是每次射击都创建并销毁一个箭矢。
编写两个脚本:TowerData,资源类型;以及 Tower。Creep、Bolt 和 CreepSpawner 已经准备好,塔的 Nearest 和 Show 也已准备好。
挑战
困难完成防御塔;Nearest(range) 和 Show() 已准备就绪。
TowerLevel:可序列化,包含公共属性range、fireEvery、damage、cost。TowerData保存public List<TowerLevel> levels。- 每隔
fireEvery秒,如果Nearest(range)找到一个小怪,就从ObjectPool<Bolt>中取出一枚 bolt,放到防御塔的位置:bolt.Launch(creep, damage, pool.Release)。 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 在线编辑器