Создание простого инвентаря в игре на Unity.

Что такое инвентарь и для чего он нужен?

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

Инвентарь

Инвентарь бывает различных типов. Так, например, в Skyrim’e используется инвентарь в виде списка. А в другой не менее известной игре – Minecraft, реализован сетчатый.

Создание простого инвентаря в игре на Unity.
Инвентарь - Minecraft

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

Дизигнем инвентарь.

Для примера будет разобран инвентарь из разрабатываемой мною игрой DarkCaves.

Инвентарь - дизайн

Не пугайтесь столь ужасного дизайна, думаю у вас он будет лучше. Разберёмся что присутствует на сцене:

  • Левые ячейки для вещей
  • Правые ячейки для вещей

Левые ячейки необходимы, чтобы отображать вещи персонажа, которые становиться активными и дают какие-либо свойства. Правые служат отображением всех вещей персонажа.

Инвентарь - иерархия

Вам стоит создать нечто подобное, разделив ячейки на две группы. Ах да, стоило бы сказать, что ячейка – это обычный объект с компонентом image.

Инвентарь - настройка ячеек

Когда всё будет готово, создаём новый скрипт, назвав его InventoryManager. Данный скрипт будет отвечать за всю логику инвентаря.

Пишем скрипт для перемещения фишек

Для начала нам стоит создать несколько функций. Первая функция будет отвечать за наведение на клетку, а вторая за сведение курсора мыши с этой клетки.

///summary /// Функция наведения на ячейку /// summary 
public void EnterCell(int id) {
    activeCell = id;
} /// summary /// Функция сведения с ячейку /// summary; 
public void ExitCell()
{
    activeCell = -1;
} 

Создадим также переменные, которые будут необходимы для управления скриптом.

[System.Serializable] // класс  вещей 
public class item {     // вещь на сцене   
    public RectTransform gameObject;
} // массив вещей
public List items = new List(); // массив плашек на сцене 
public List cells = new List();
[Space(10)] // канвас 
public RectTransform canvas;
[Space(10)] // активная ячейка 
public int activeCell = -1; // предыдущая активная ячейка 
public int oldActiveCell = -1; 

Немного разберёмся, что, зачем и почему:

  • Items – это массив класса в котором будут содержаться различные характеристики о вещи, например сколько она добавляет здоровья, брони, и прочее. На данный момент я не стал этого вносить, поскольку это бы заняло невероятно много времени.
  • cells – массив ячеек инвентаря, которые были созданы ранее, они нужны для того, чтобы прикреплять объект вещи к конкретной точке, а не в пространстве.
  • canvas – элемент, необходимый для перемещения вещи.
  • activeCell и oldActiveCell – переменные для расчётов.

Следующая функция, которая необходима для работы скрипта – это Update.

void Update() {
    if (Input.GetKeyDown(KeyCode.Mouse0)) // если нажата клавиша мыши     
    {
        if (activeCell != -1 && items[activeCell].gameObject != null) // если выделена активная ячейка    
        {
            items[activeCell].gameObject.parent = canvas; // меняем родителя 
            oldActiveCell = activeCell; // запоминаем ячейку   
        }
    }
    if (Input.GetKey(KeyCode.Mouse0)) // если клавиша нажата   
    {
        if (oldActiveCell != -1) // если в памяти лежит какая - то ячейка  
        {
            float x = Input.mousePosition.x / Screen.width * canvas.sizeDelta.x; // вычисляем координаты мыши     
            float y = Input.mousePosition.y / Screen.height * canvas.sizeDelta.y; // вычисляем координаты мыши      
            items[oldActiveCell].gameObject.anchoredPosition = new Vector2(x, y); // перемещаем ячейку     
        }
    }
    if (Input.GetKeyUp(KeyCode.Mouse0)) // если клавиша мыши отжата    
    {
        if (activeCell != -1) // если выделена какая-то ячейка        
        {
            if (items[activeCell].gameObject == null) // проверяем существует ли там вещь 
            {
                if (oldActiveCell != -1) { // если в памяти лежит какая - то ячейка     
                    items[activeCell].gameObject = items[oldActiveCell].gameObject; // перемещаем выделенной ячейке, элемент из памяти     
                    items[oldActiveCell].gameObject = null; // старый элемент удаляем              
                    items[activeCell].gameObject.parent = cells[activeCell]; // меняем родителя      
                    items[activeCell].gameObject.anchoredPosition = new Vector2(40, 40); // ставим в нулевые координаты 50 - половина ширины изображения        
                }
            }
            else
            {
                if (oldActiveCell != -1) {
                    Debug.Log("Место для фишки занято, возвращаю назад");
                    items[oldActiveCell].gameObject.parent = cells[oldActiveCell];
                    items[oldActiveCell].gameObject.anchoredPosition = new Vector2(40, 40);
                }
            }
        }
        else {
            if (oldActiveCell != -1)
            {
                Debug.Log("Фишка перемещена в пустое пространство, возвращаю назад");
                items[oldActiveCell].gameObject.parent = cells[oldActiveCell];
                items[oldActiveCell].gameObject.anchoredPosition = new Vector2(40, 40);
            }
        }
        oldActiveCell = -1;
    }
} 

Разберёмся, что здесь происходит. В первую очередь, мы проверяем нажатие на клавишу мыши. Если нажатие было произведено, то мы проверяем, был ли наведён курсор на какую-то из ячеек. Если такое произошло, запоминаем номер данной ячейки и меняем родителя у объекта.

Далее происходит проверка на постоянное нажатие клавиши мыши. Если клавиша мыши зажата, и у нас был зафиксирован номер ячейки, мы вычисляем координаты курсора и перемещаем ячейку в их позицию.

Ну и последнее что происходит в этой функции, это проверка не была ли отжата клавиша мыши. Если такое произошло, мы проверяем был ли наведён курсор на ячейку, и не лежит ли в этой ячейке какой-либо элемент. Если все условия соблюдены, элемент перемещается в данную ячейку инвентаря, если нет – возвращается обратно.

На этом написание скрипта закончено, осталось только настроить сцену.

Настройка сцены для скрипта.

Для начала закинем скрипт на какой ни будь объект на сцене.

Инвентарь - настройка скрипта

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

Инвентарь - настройка вещей

На сами ячейки необходимо добавить компонент EventTrigger и указать у него следующие настройки. Не запутайтесь с id ячейки. Необходимо начать с 0, далее 1, 2, 3 …

Инвентарь - триггер на ячейке

Предпоследним действием нужно добавить Image в переменную скрипта. Поскольку у меня 18 ячеек, я создал массив из 18 элементов. Где 17 позиций пустые и только лишь в первом указана вещь.

Инвентарь - настройка вещей 2

Осталось лишь указать 18 позиций, на которые перемещаются вещи:

Инвентарь - настройка скрипта 2

На этом разработка инвентаря для перемещения закончена. Если вы всё сделали правильно, то при перетаскивании Image, вы можете наблюдать за тем, как элемент подстраивается под курсор и при отпускании в другую ячейку принимает её позицию.

Автор статьи: Александр Каримов.

5/5 (1)

Оцените