Цель: дальнейшая организация и создание более масштабируемого кода с помощью наследования классов.

В ООП наследование позволяет новым объектам приобретать свойства существующих объектов. Давайте рассмотрим пример конкретного наследования классов с нашим классом Item. В нашей игре мы решили, что каждый предмет имеет следующие особенности:

using UnityEngine;

public class Item {
    
    public string name;
    public int itemID;
    public string description;
    public Sprite icon;
}

Когда вы сравниваете хлеб Item с мечом Item, они очень разные. Хлеб можно потреблять, а у меча могут быть характеристики, связанные с боем.

Есть ли смысл загромождать класс Item и потенциально переписывать много кода? Нет.

Хочешь спагетти-код? Точно нет.

Вместо этого мы можем перейти к наследованию классов, где мы определяем Оружие как смещение к Предмету. Итак, это выглядит следующим образом: у нас есть класс Item, и мы можем создать класс Weapon с новыми свойствами, специфичными для Weapon:

public class Weapon : Item {
    
    public int attackBonus;
    public int prayerBonus;
    public int strengthBonus;
    public int magicBonus;
}

Оружие по-прежнему имеет название, идентификатор предмета и значок. Вы можете перезаписать существующие свойства предмета в этом классе оружия, поскольку мы его наследуем, если хотите. Мы делаем это, написав новый метод в дочернем пользовательском классе. Это выглядит так:

public class Weapon : Item {

    public int attackBonus;
    public int prayerBonus;
    public int strengthBonus;
    public int magicBonus;

    void ChangeID() {
        itemID = 4;
    }
}

Если бы существовал другой itemID, вместо него мы использовали бы base.itemID = 4;. При использовании ключевых слов this и base this относится к этому экземпляру, а base относится к тому, что вы можете сделать с этим экземпляром из родительского класса.

Мы также можем создать расходуемый тип Item:

public class Consumable : Item {

    public int addedHealth;
    public bool poisoned;
}

Затем мы запускаем скрипт MonoBehaviour с именем ItemDatabase, в котором хранятся все элементы нашей игры. Здесь важно отметить, что меч также является предметом. То же самое с хлебом. И меч, и хлеб унаследованы от Item. Мы можем создавать такие элементы:

using UnityEngine;

public class ItemDatabase : MonoBehaviour {
    
    [SerializeField] private Item goldCoin = new Item();
    [SerializeField] private Weapon sword = new Weapon();
    [SerializeField] private Consumable bread = new Consumable();
}

Мы хотим видеть наши предметы в инспекторе, поэтому нам нужно вернуться к нашим классам Item, Weapon и Consumable. Поскольку элементы не являются моноповедениями, нам нужно добавить атрибут [System.Serializable] в начало всех этих классов.

Обратите внимание, что в инспекторе у меча и хлеба также есть три начальных черты каждого предмета(имя, идентификатор предмета, значок), за которыми следуют настраиваемые свойства (поля экземпляра):

Наследование классов позволяет нам создавать и классифицировать наши предметы, оружие и расходные материалы, поэтому наш скрипт Item не загроможден внутри. Это намного удобнее и аккуратно написано.

Помните, в этом случае у вас может быть очень много предметов. Им не всем нужны индивидуальные черты. Как правило, предметы представляют собой просто набор предметов, которые вы можете собирать. Нет смысла иметь объект MonoBehaviour для каждого предмета, т. е. хлеба, меча, жезла, золотой монеты, и каждый раз переписывать свойства. В этом примере было бы лучше иметь класс Item, а затем извлекать черты персонажа из этого POCO через наследование класса.