
Приветствую начинающих разработчиков! В данной статье мы научимся создавать два вида магазина: магазин ресурсов, и магазин предметов. В магазине ресурсов, покупные ресурсы отображаются на игровой сцене в виде чисел, а в магазине предметов, каждый купленный предмет отдельно друг от друга отображается в ячейках нашего инвентаря.
И начнём мы данную статью с более простого магазина, то-есть, с магазина ресурсов.
Магазин ресурсов
Суть данного магазина следующая. У нас есть игровые монеты, и два вида ресурсов для покупок: еда и вода. При нажатии на первую кнопку, за монеты покупается вода, а при нажатии на вторую покупку, покупается еда. Количество еды и воды будет отображаться на экране в виде чисел.
Подготовительная часть
Предлагаю для начала подготовить наш проект. Для этого с помощью окна Hierarchy создадим несколько объектов.
- Создайте канвас, и по желанию можете настроить его (UI - Canvas).
- Внутри канваса создайте 3 текстовых объекта типа UI - Text - TextMeshPro. В них будет содержаться информация о количестве еды, воды, и монет. Поэтому назовите данные объекты Food, Water и Money.
- Внутри канваса создайте 2 кнопки типа UI - Button - TextMeshPro для покупок еды и воды. Назовём эти объекты BuyFood и BuyWater.
- Создайте один пустой объект типа Create Empty. Назовите его как угодно, например Player. Если у вас уже есть объект с таким названием, то можете данный объект не создавать. Этот объект нужен исключительно для хранения информации о количестве монет, и купленных вами ресурсов.
В результате на игровой сцене и в окне Hierarchy должен быть примерно такой результат.

Подготовительная часть завершена. Теперь перейдём к основной скриптовой части
Работа со скриптами
Первым делом создадим C# скрипт с названием PlayerResources, и заранее присвоим его нашему объкту Player. В этом скрипте будет находится вся информация о количестве наших моент, воды и еды.
Впишем в данный скрипт следующий код:
using UnityEngine;
using TMPro;
public class PlayerResources : MonoBehaviour
{
public int money = 150;
public int water = 0;
public int food = 0;
public TextMeshProUGUI textMoney;
public TextMeshProUGUI textWater;
public TextMeshProUGUI textFood;
void Start()
{
UpdateText();
}
public void UpdateText()
{
textMoney.text = "Монет: " + money.ToString();
textWater.text = "Воды: " + water.ToString();
textFood.text = "Еды: " + food.ToString();
}
}
Как видим, в строках #6-12 мы создали переменные для количества монет, еды и воды, а так же создали ссылки на тектовые объекты. Предлагаю заранее перетащить в поля textMoney, textWater и textFood соответствующие объекты.

Вернёмся к разбору кода. Далее при старте игры мы запускаем метод UpdateText(), в котором заносим количество наших монет и ресурсов в текстовые поля на игровой сцене. И если вы сейчас запустите проект, вы увидите, что значения из скрипта отобразятся в ваших текстовых полях.
Теперь создадим скрипт для магазина, в котором будут отображены стоимости ресурсов. Создадим c# скрипт с названием Shop, и заранее перетащим его, например на наш объект канваса. В скрипт впишем следующее содержимое:
using UnityEngine;
public class Shop : MonoBehaviour
{
public PlayerResources resourcePlayer;
public int costFood = 10;
public int costWater = 15;
public void BuyFood()
{
if (resourcePlayer.money >= costFood)
{
resourcePlayer.money -= costFood;
resourcePlayer.food += 1;
resourcePlayer.UpdateText();
}
}
public void BuyWater()
{
if (resourcePlayer.money >= costWater)
{
resourcePlayer.money -= costWater;
resourcePlayer.water += 1;
resourcePlayer.UpdateText();
}
}
}
Как вы могли заметить, в начале скрипта мы указали стоимость для воды и еды, а так же создали ссылку на созданный нами ранее скрипт PlayerResources, который находится на объекте Player. Поэтому предлагаю заранее в окне Inspector для объекта Canvas перетащить в поле Resource Player объект Player.

Так же в данном скрипте мы создали два метода: BuyFood() и BuyWater(), для покупки еды и воды. Здесь нет ничего сложного. Сначала мы проверяем, хватает ли наших монет для приобретения товара. И если да, то отнимает монеты, и прибавляем ресурс, а так же обновляем все наши изменения на игровой сцене.
Теперь нам необходимо эти два метода присвоить нашим кнопкам. Для этого выбираем наш объект BuyFood, и в окне Inspector, в поле On Click() перетаскиваем объект Canvas(!1). А потом выбираем скрипт Shop и метод BuyFood(!2).

После проделывания таких же манипуляций и со второй кнопкой BuyWater, можете запустить игру и убедиться всё что работает. Еда и вода покупается, а монеты отнимаются.
Магазин предметов
На самом деле, магазин по продажи ресурсов это самый простой магазин, который можно себе представить. Сейчас мы немного улучшим наш магазин, и допишем в него возможность покупать не только ресурсы, но и 2 дополнительных предмета: мечь и топор, которые будут заноситься в наш инвентарь. Для этого немного подготовим проект.
Подготовительная часть
Первым делом с помощью окна Hierarchy создадим несколько дополнительных объектов:
- Внутри объекта Canvas создайте 2 кнопки типа UI - Button - TextMeshPro. Они нужны для покупки меча и топора. Назовём эти объекты BuySword и BuyAxe.
- Внутри объекта Canvas создадим пустой объект с названием Slots. Он нам нужен исключительно для группировки наших слотов инвентаря. Можно впринципе обойтись и без него, но с ним удобнее.
- Внутри объекта Slots создайте 5 объектов типа UI - Image. Это и будут наши слоты, в которых будут храниться купленные предметы. Назовите их Slot1, Slot2, и так далее.
На игровой сцене и в окне Hierarchy должны произойти следующие изменения:

Отлично. Теперь заранее создадим 2 префаба для изображений нашего меча и топора, на основе объекта UI - Image, которые в дальнейшем после покупок будут отображаться в нашем инвентаре.

Работа со скриптами
Пришло время к изменению наших скриптов. Начнём со скрипта PlayerResources. В начало нашего класса допишем следующие строчки:
public bool[] isFull;
public GameObject[] slots;
В первой строке хранится информация о заполнении слотов нашего инвентаря. А во второй строчке мы храним ссылки на эти слоты. Предлагаю сразу же с помощью окна Inspector для объекта Player создать 5 слотов, и перетащить в них наши объекты слотов.

Итоговый код в скрипте PlayerResources выглядит так:
using UnityEngine;
using TMPro;
public class PlayerResources : MonoBehaviour
{
public int money = 100;
public int water = 0;
public int food = 0;
public TextMeshProUGUI textMoney;
public TextMeshProUGUI textWater;
public TextMeshProUGUI textFood;
public bool[] isFull;
public GameObject[] slots;
void Start()
{
UpdateText();
}
public void UpdateText()
{
textMoney.text = "Монет: " + money.ToString();
textWater.text = "Воды: " + water.ToString();
textFood.text = "Еды: " + food.ToString();
}
}
Теперь отредактируем скрипт Shop, и объявим 4 дополнительных переменных.
public int costSword = 20;
public int costAxe = 25;
public GameObject Sword;
public GameObject Axe;
Первые 2 переменные указывают цену меча и топора, а вторые 2 объекта указывают ссылку на префаб меча и топора. Давайте заранее в окне Inspector для объекта Canvas перетащим наши префабы в данные поля.

Так же мы создали 2 дополнительных метода: BuySword() и BuyAxe(), которые нам нужны для покупки меча и топора.
public void BuySword()
{
for (int j = 0; j < resourcePlayer.slots.Length; j++)
{
if (resourcePlayer.isFull[j] == false)
{
if (resourcePlayer.money >= costSword)
{
resourcePlayer.money -= costSword;
resourcePlayer.UpdateText();
Instantiate(Sword, resourcePlayer.slots[j].transform);
resourcePlayer.isFull[j] = true;
break;
}
}
}
}
public void BuyAxe()
{
for (int j = 0; j < resourcePlayer.slots.Length; j++)
{
if (resourcePlayer.isFull[j] == false)
{
if (resourcePlayer.money >= costAxe)
{
resourcePlayer.money -= costAxe;
resourcePlayer.UpdateText();
Instantiate(Axe, resourcePlayer.slots[j].transform);
resourcePlayer.isFull[j] = true;
break;
}
}
}
}
Разбирать данный код мы не будем, поскольку они работают примерно по такому же принципу что и при покупке ресурсов, за исключением того, что здесь имеется проверка на наличие пустой ячейки, перед совершением покупки. А создание предмета в инвентаре мы сделали с помощью метода Instantiate().
Итоговый код скрипта Shop выглядит следующим образом:
using UnityEngine;
public class Shop : MonoBehaviour
{
public PlayerResources resourcePlayer;
public int costFood = 10;
public int costWater = 15;
public int costSword = 20;
public int costAxe = 25;
public GameObject Sword;
public GameObject Axe;
public void BuyFood()
{
if (resourcePlayer.money >= costFood)
{
resourcePlayer.money -= costFood;
resourcePlayer.food += 1;
resourcePlayer.UpdateText();
}
}
public void BuyWater()
{
if (resourcePlayer.money >= costWater)
{
resourcePlayer.money -= costWater;
resourcePlayer.water += 1;
resourcePlayer.UpdateText();
}
}
public void BuySword()
{
for (int j = 0; j < resourcePlayer.slots.Length; j++)
{
if (resourcePlayer.isFull[j] == false)
{
if (resourcePlayer.money >= costSword)
{
resourcePlayer.money -= costSword;
resourcePlayer.UpdateText();
Instantiate(Sword, resourcePlayer.slots[j].transform);
resourcePlayer.isFull[j] = true;
break;
}
}
}
}
public void BuyAxe()
{
for (int j = 0; j < resourcePlayer.slots.Length; j++)
{
if (resourcePlayer.isFull[j] == false)
{
if (resourcePlayer.money >= costAxe)
{
resourcePlayer.money -= costAxe;
resourcePlayer.UpdateText();
Instantiate(Axe, resourcePlayer.slots[j].transform);
resourcePlayer.isFull[j] = true;
break;
}
}
}
}
}
Чтобы методы BuySword() и BuyAxe() работали, необходимо для объектов BuySword и BuyAxe с помощью окна Inspector в поле On Click() присвоить эти методы, как мы это делали и с предыдущими кнопками.
Наш магазин готов. Теперь вы можете запустить данный проект, и протестировать его работоспособность. Если остались вопросы по работе данного магазина, задавайте их в комментариях.