Абстрактные компоненты
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 3 из 64.
Некоторые базовые классы описывают тип объектов, который никогда не существует сам по себе. Любое оружие стреляет, но оружие, которое не является ни пистолетом, ни дробовиком, стрелять не может. Пометь такой класс как abstract, а каждый шаг, который должны реализовать его подклассы, объяви абстрактным методом без тела:
public abstract class Weapon : MonoBehaviour
{
public int shots;
public void Pull()
{
shots++;
Fire();
}
protected abstract void Fire();
}public class Shotgun : Weapon
{
public GameObject pelletPrefab;
protected override void Fire()
{
for (int i = -1; i <= 1; i++)
{
Instantiate(pelletPrefab, transform.position + transform.right * i * 0.3f, transform.rotation);
}
}
}Подкласс, в котором не реализован Fire, не компилируется: CS0534, 'Pistol' does not implement inherited abstract member 'Weapon.Fire()'. Unity также не позволяет добавить абстрактный скрипт на объект. Перетащи Weapon на объект — и появится сообщение Can't add script behaviour 'Weapon'. The script class can't be abstract!, поскольку Unity не может создать Weapon без Fire.
Другие скрипты по-прежнему работают с базовым типом. GetComponent<Weapon>() возвращает подкласс, прикреплённый к объекту, а Pull() вызывает Fire этого подкласса:
// Player.cs
private Weapon weapon;
void Start()
{
weapon = GetComponent<Weapon>();
}
void Update()
{
if (Mouse.current.leftButton.wasPressedThisFrame)
{
weapon.Pull();
}
}Замени компонент Shotgun на Pistol, и скрипт Player останется прежним.
Задание
ЛегкоСделай Monster абстрактным, чтобы башня могла атаковать монстров всех видов.
- В
Monsterнапишиpublic abstract class Monsterиprotected abstract void React();без тела метода. - Теперь компилятор указывает на
Imp: добавьprotected override void React(), который прибавляетVector3.forward * 2fк позиции. - В
Tower, внутри цикла, вызовиZap()дляtarget.GetComponent<Monster>().
Нажми «Играть» и пробел: слаймы уменьшаются, а бес прыгает назад. Затем нажми «Проверить».
Попробуйте сами
using UnityEngine;
// Что общего у всех монстров.
public class Monster : MonoBehaviour
{
public int hp = 3;
public void Zap()
{
hp--;
if (hp <= 0)
{
Destroy(gameObject);
}
else
{
React();
}
}
// Как этот вид монстров реагирует на удар током, после которого выживает.
protected virtual void React()
{
}
}
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыКомпоненты работают вместеПовторение: модульная турельПовторение: спаренная пушка4Сериализованные данные
Сериализуемые классыСписки в инспектореПеречисления в инспектореПовторение: таблица добычиПовторение: определяем добычу2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействияПовторение: ближайший в пределах досягаемости5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиСохраняем ветерВолны как данныеПовторение: база предметовПовторение: покупка в магазинеПотренируйтесь самостоятельно: Песочница Unity