Menu
CoddyTech

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 или компонент и запрашивают у него интерфейс, как это делает огненный шар.

challenge icon

Задание

Легко

Гигант охраняет деревенскую площадь. Стрелки управляют Гигантом (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
{
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Архитектура игр в Unity