IDamageable
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 6 из 50.
В игре многое можно повредить, и у этих объектов мало общего: у игрока есть очки здоровья, а ящик разбивается от первого удара. Общий базовый класс объединил бы их в одну группу. Интерфейс называет единственное, что у них общего, а каждый скрипт реализует его по-своему:
public interface IDamageable
{
void TakeDamage(int amount);
}public class PlayerHealth : MonoBehaviour, IDamageable
{
public int hp = 10;
public void TakeDamage(int amount)
{
hp -= amount;
Debug.Log("Ouch! hp: " + hp);
}
}public class Crate : MonoBehaviour, IDamageable
{
public void TakeDamage(int amount)
{
Destroy(gameObject);
}
}У скрипта по-прежнему один базовый класс — MonoBehaviour, а интерфейсы перечисляются после него. Интерфейс помещается в отдельный файл IDamageable.cs и не наследуется от MonoBehaviour: это не компонент, и сам по себе он никогда не добавляется на объект. В классе, где он перечислен, должен быть публичный метод TakeDamage(int), иначе код не скомпилируется.
Объект, наносящий урон, запрашивает интерфейс, а не конкретный класс:
// Fireball.cs
void OnCollisionEnter(Collision collision)
{
IDamageable target = collision.gameObject.GetComponent<IDamageable>();
if (target != null)
{
target.TakeDamage(3);
}
Destroy(gameObject);
}Огненный шар наносит урон игроку и разбивает ящики с помощью одних и тех же строк кода, а для добавленного позже типа цели ничего здесь менять не нужно. Unity не отображает в Inspector поле типа интерфейса, поэтому скрипты хранят GameObject или компонент и запрашивают у него интерфейс, как это делает огненный шар.
Задание
ЛегкоГигант охраняет деревенскую площадь. Стрелки управляют Гигантом (Mover.cs, готово), а клавиша Space приводит в движение его молот: Hammer.cs вызывает Slam(), которая находит все коллайдеры в пределах radius. Три объекта на площади получают удар, каждый по-своему, и больше ничем не делятся:
Snowman: каждое очко урона уменьшает его размер на 0.25 по каждой оси (начальный размер — 1.5). При размере 0.5 или меньше он тает: уничтожь снеговика.Bell: выводитDongодин раз за каждое очко урона (при ударе силой 2 выводит его дважды) и добавляет очки кrings.Scarecrow: от первого удара он падает, поворачиваясь на 90 градусов вокруг оси z, независимо от силы урона. Последующие удары ничего не меняют.
IDamageable.cs объявляет интерфейс с одним методом: void TakeDamage(int amount). Реализуй его в Snowman, Bell и Scarecrow, задав каждому свою реакцию. Затем в Slam вызывай TakeDamage(power) у IDamageable каждого найденного коллайдера. Коллайдеры без него, например земля, пропускаются.
Нажми Play, подойди к каждому из них и нанеси удар, затем нажми Check.
Попробуйте сами
using UnityEngine;
public class Snowman : MonoBehaviour
{
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыСовместная работа компонентовПовторение: модульная турель4Сериализованные данные
Сериализуемые классыСписки в InspectorПеречисления в InspectorПовторение: таблица лута2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействия5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиВолны как данныеПовторение: база предметов