Menu
CoddyTech

IDamageable

Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 7 z 64.

Interfejs to lista metod, które klasa zobowiązuje się udostępniać, ale bez kodu tych metod. Klasy, które poza tym nie mają ze sobą nic wspólnego, mogą złożyć tę samą obietnicę. W zwykłym C#:

interface IGreeter
{
    string Greet();
}

class Robot : IGreeter
{
    public string Greet() { return "Beep"; }
}

class Cat : IGreeter
{
    public string Greet() { return "Meow"; }
}

Zmienna typu IGreeter może przechowywać obiekt klasy Robot lub Cat, a greeter.Greet() uruchamia metodę obiektu, który aktualnie przechowuje. Klasa, która wymienia IGreeter, ale nie ma publicznej metody Greet(), nie kompiluje się.

W grze wiele rzeczy może otrzymywać obrażenia, choć poza tym niewiele je łączy: gracz ma punkty życia, a skrzynia rozpada się po pierwszym trafieniu. Wspólna klasa bazowa zmusiłaby je do przynależności do jednej rodziny. Interfejs określa tę jedną wspólną cechę, a każdy skrypt implementuje go na swój sposób:

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);
    }
}

Skrypt nadal ma jedną klasę bazową, MonoBehaviour, a interfejsy wymienia po niej. Interfejs umieszcza się w osobnym pliku, IDamageable.cs, i nie dziedziczy on po MonoBehaviour: nie jest komponentem i nigdy nie dodaje się go samodzielnie do obiektu. Klasa, która go wymienia, musi mieć publiczną metodę TakeDamage(int), inaczej się nie skompiluje.

Obiekt zadający obrażenia odwołuje się do interfejsu, a nie do klasy:

// Fireball.cs
void OnCollisionEnter(Collision collision)
{
    IDamageable target = collision.gameObject.GetComponent<IDamageable>();
    if (target != null)
    {
        target.TakeDamage(3);
    }
    Destroy(gameObject);
}

Kula ognia zadaje obrażenia graczowi i niszczy skrzynie, używając tych samych instrukcji. Dodanie później nowego rodzaju celu nie wymaga żadnych zmian w tym miejscu. Unity nie wyświetla w Inspectorze pola typu interfejsu, więc skrypty przechowują GameObject lub komponent i pobierają z niego interfejs, tak jak robi to kula ognia.

challenge icon

Wyzwanie

Łatwy

Spraw, by bałwan, dzwon i strach na wróble implementowały IDamageable, aby młot mógł je uderzać.

  1. Snowman: TakeDamage zmniejsza go o 0.25f * amount na każdej osi; gdy osiągnie 0.5 lub mniej, zniszcz go.
  2. Bell: wypisz Dong raz za każdy punkt i dodaj amount do rings.
  3. Scarecrow: tylko pierwsze uderzenie uruchamia transform.Rotate(0f, 0f, 90f);.
  4. W Slam wywołaj TakeDamage(power) dla obiektu IDamageable każdego collidera, jeśli taki istnieje.

Naciśnij „Graj” i uderz każdy obiekt. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

using UnityEngine;

public class Snowman : MonoBehaviour
{
}

Wszystkie lekcje w sekcji Architektura gier w Unity

Poćwicz samodzielnie: Edytor online Unity