Komponenty abstrakcyjne
Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 3 z 50.
Niektóre klasy bazowe opisują rodzaj obiektu, który nigdy nie istnieje samodzielnie. Każda broń strzela, ale broń, która nie jest ani pistoletem, ani strzelbą, nie ma sposobu, by strzelać. Oznacz taką klasę jako abstract, a każdy krok, który muszą zaimplementować jej podklasy, zadeklaruj jako metodę abstrakcyjną, bez treści:
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);
}
}
}Podklasa, w której nie zaimplementujesz Fire, nie skompiluje się: CS0534, 'Pistol' does not implement inherited abstract member 'Weapon.Fire()'. Unity nie pozwala też dodać abstrakcyjnego skryptu do obiektu. Przeciągnij Weapon na obiekt, a zobaczysz komunikat Can't add script behaviour 'Weapon'. The script class can't be abstract!, ponieważ Unity nie mogłoby utworzyć broni, która nie ma metody Fire.
Inne skrypty nadal mogą korzystać z typu bazowego. GetComponent<Weapon>() zwraca podklasę znajdującą się na obiekcie, a Pull() uruchamia metodę Fire tej podklasy:
// Player.cs
private Weapon weapon;
void Start()
{
weapon = GetComponent<Weapon>();
}
void Update()
{
if (Mouse.current.leftButton.wasPressedThisFrame)
{
weapon.Pull();
}
}Zastąp komponent Shotgun komponentem Pistol, a skrypt Player pozostanie bez zmian.
Wyzwanie
ŁatwyWieża czarodzieja razi potwory na polu. Monster.cs zawiera to, co łączy wszystkie potwory: hp (3) i Zap(), która odejmuje 1 punkt hp, niszczy potwora przy 0, a w przeciwnym razie wywołuje React(). Slime.cs reaguje, zmniejszając swój rozmiar. Imp.cs nie ma reakcji, a Monster przypisuje mu pustą metodę React, więc nic nie informuje Cię o jej braku.
- Zrób z Monster klasę abstrakcyjną, a z React metodę abstrakcyjną, aby potwór, który nie określa, jak reaguje, nie kompilował się. Kompilator wskaże wtedy Imp.
- Napisz metodę React dla Imp: skacze o 2 jednostki do tyłu, z dala od wieży (wzdłuż osi +z).
- W Tower.cs, gdy naciśnięty jest spacja, pobierz komponent Monster każdego obiektu oznaczonego tagiem Monster, niezależnie od jego rodzaju, i wywołaj na nim
Zap().
Naciśnij Play i raź potwory, a następnie naciśnij Check.
Spróbuj swoich sił
using UnityEngine;
// Co łączy wszystkie potwory.
public class Monster : MonoBehaviour
{
public int hp = 3;
public void Zap()
{
hp--;
if (hp <= 0)
{
Destroy(gameObject);
}
else
{
React();
}
}
// Jak ten rodzaj potwora reaguje na trafienie, które przetrwał.
protected virtual void React()
{
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Architektura gier w Unity
1Komponenty, nie hierarchie
Małe komponentyPodstawowy skrypt przeciwnikaKomponenty abstrakcyjneWspółpracujące komponentyPodsumowanie: modułowa wieżyczka4Dane serializowane
Klasy serializowalneListy w InspectorzeWyliczenia w InspectorzePodsumowanie: tabela łupów10Projekt: Arena przetrwania
BohaterTypy wrogów2Interfejsy w Unity
IDamageableInterfejsy i TryGetComponentGetComponentsPodsumowanie: klawisz interakcji5ScriptableObjects
Zasoby danychStatystyki broniWspółdzielone ustawieniaFale jako danePowtórka: baza danych przedmiotów8Kod wielokrotnego użytku
Metody rozszerzająceGeneryczny singletonGeneryczne metody pomocniczePodsumowanie: FindNearest