Как создать инвентарь в Unity 5 при помощи UI

В этом уроке мы разберем как создать инвентарь для RPG игр (или их подобрых) с выбором предмета в Unity 5 при помощи UI. Если вы не знаете, как взаимодействовать с UI, или как сделать его масштабируемым, то рекомендую посмотреть прошлый урок на эту тему.

Итак, изначально, создадим класс нашего предмета, который будет лежать в инвентаре и который будет хранить данные для выгрузки:

public class InventoryItem {
    //Код предмета
    public int Id;
    //Его имя (его можно изменять, давать оружиям
    //имена, так как все расчеты будут производится
    //относительно Id предмета
    public string Name;
    
    //Создадим конструктор для создания предметов
    public InventoryItem(int id,string name)
    {
        Id = id;
        Name = name;
    }
}

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

public class InventorySlot {
    //ссылка на предмет
    public InventoryItem Item;

    //конструктор для создания пустого слота
    public InventorySlot()
    {
       
    }
    //конструктор для создания слота с предметом
    public InventorySlot(InventoryItem item)
    {
        Item = item;
    }
}

После реализации наших двух классов необходимо сделать UI для отображения наших предметов. Создадим Canvas, который назовем InventoryCanvas и сразу выставим настройки масштаба, чтобы наш UI не сместился потом. В нем создадим ScrollView и назовем его InventoryHolder.

Теперь нужно разобраться со всеми свойствами ScrollView и его компонента ScrollRect. ScrollRect имеет в себе такие свойства:
Content - Просматриваемый элемент, который можно листать/перемещать
Horizontal - Разрешено ли перемещение по горизонтали, выключим его
Vertical - Разрешено ли перемещение по вертикали
Movement Type - Тип перемещения, имеет в себе 3 вида: Elastic(Работает по типу резинки, может оттягиваться, вылезая за границей Content и возвращаться в исходное положение со скоростью, зависящей от параметра Elasticity),Unrestricted(передвижение Content не ограничивается, можно выходить далеко за пределы),Clamped(передвижение не может выйти за пределы контейнера)
Inertia - Инерция, скорость которой зависит от DecelerationRate
Scroll Sensitivty - Чувствительность к колесику мыши и движениям тачпада
Viewport - Объект, который содержит в себе просматриваемые элементы
Horizontal/Vertical scrollbar - ссылки на скроллбары, visibility отвечает за показ. Для Horizontal установим Visibility в значение Auto Hide, а для Vertical в Pernament, тогда у нас будет всегда активен вертикальный скроллбар, а горизонтальный будет всегда скрыт.

На этом мы разбрались с необходимыми нам свойствами ScrollView и продолжим создание инвентаря. Для этого нам необходимо добавить на объект Content новый компонент GridLayoutGroup. GridLayoutGroup сам распределяет объекты внутри себя, выставляя им нужный размер и сортируя внутри объекта.

GridLayoutGroup имеет такие свойства:
Padding - Выставляет, на каком расстоянии от краёв начнут распологаться элементы
Cell Size - Размер ячейки
Spacing - Размер пробела между ячейками (Я выставил эти настройки так, чтобы помещалось 4 ячейки на одной полосе)
Start Corner - С какой позиции у нас будут идти ячейки (если создать три ячейки и поменять на Upper Right, то они будут нумероваться справа налево)
Start Axis - по какой оси будут добавляться элементы
Child Alignment - откуда начинает добавлять элементы
Constrait - Выставляет настройки по количеству объектов в строке/столбце

Выствив нужные настройки в GridLayoutGroup создадим префаб нашего контейнера для предмета и сохраним его в папке Resources/Prefub с названием InventoryCell. Пусть это будет обычный Button. В итоге при добавлении можества наших контейнеров вид будет таким:

Вид инвентаря в Unity3d

Теперь необходимо создать скрипт, который бы связал наши данные и отображал их. Создадим новый скрипт ViewContoller, который повесим на InventoryCanvas:

public class ViewController : MonoBehaviour {

    public List Inventory;
    public Transform InventoryContent;
    void Start()
    {
        Inventory = new List();
        //Добавим 20 слотов в наш инвентарь
        for (int i = 0; i < 20; i++)
        {
            Inventory.Add(new InventorySlot());
        }
        //добавим несколько предметов
        Inventory[0].Item = new InventoryItem(0, "Bow");
        Inventory[1].Item = new InventoryItem(1, "Sword");
        Inventory[2].Item = new InventoryItem(2, "Pike");
        //И загрузим их
        UpdateAll();
    }
    void UpdateAll()
    {
        //Если инвентарь больше или меньше текущих слотов
        if (Inventory.Count!=InventoryContent.childCount)
        {
            for (int i = InventoryContent.childCount - (InventoryContent.childCount-Inventory.Count); i < InventoryContent.childCount; i++)
            {//Удаляем лишние элементы
                Destroy(InventoryContent.GetChild(i).gameObject);
            }
            for (int i = Inventory.Count - (Inventory.Count - InventoryContent.childCount); i < Inventory.Count; i++)
            {//Добавляем, если нехватает
                Instantiate(Resources.Load("Prefub/InventoryCell"),InventoryContent);
            }
        }
        //Выставляем размер для нашего Content, чтоб он соответствовал кол-ву ячеек 
        //(Mathf.Floor(Inventory.Count / 4)*90+30) это высота, вычисления тут могут меняться
        //в зависимости от требований вашего инвентаря
        InventoryContent.GetComponent().sizeDelta = new Vector2(InventoryContent.GetComponent().sizeDelta.x,Mathf.Floor(Inventory.Count / 4)*90+30);
 
        for (int i = 0; i < InventoryContent.childCount; i++)
        {
            //удаляем предыдующие методы на кнопке
            InventoryContent.GetChild(i).GetComponent<button>().onClick.RemoveAllListeners();
            //Создаем новую переменную (иначе все кнопки примут финальное значение i)
            int id = new int();
            //запоминаем текущую i
            id = i;
            //Вызываем метод выбора предмета с текущей i
            InventoryContent.GetChild(i).GetComponent<button>().onClick.AddListener(delegate () { SelectItem(id); });
        }
    }
    void SelectItem(int SlotId)
    {
        //Проверяем, не пуст ли слот и выводим
        //информацию о нем
        if (Inventory[SlotId].Item!=null)
            Debug.Log(Inventory[SlotId].Item.Name);
        else
            Debug.Log("EmptyItem");
    }
}

Не забудте связать InventoryContent с Content в InventoryHolder. Теперь при запуске мы будем выгружать данные о наших предметах и выводить их на экран, а при нажатии производить действия с данной ячейкой. Это будет выглядеть так:

Реализованный инвентарь в Unity3d

В итоге данного урока мы создали инвентарь в Unity 5 при помощи UI с выбором предмета. Данный инвентарь можно доделывать. Можно, например, сделать перемещение предметов между слотами, так же, такой инвентарь можно сохранять, а если вы этого не умеете делать, можете посмотреть мой предыдущий урок.

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (7 оценок, среднее: 3,29 из 5)
Adblock
detector