Предметы в Unity. В этой статье мы научимся создавать механику собираемых предметов, но без инвентаря в Unity. В каждой игре существует огромное количество различных механизмов, которые работают как часы. Будь то убывание полоски жизни в случае получения урона, прыжки, двойные прыжки, боевая система, броски гранат, поднятие предметов и так далее — все это называется игровыми механиками.
Unity — как сделать собираемые предметы с отрисовкой значений в интерфейсе
Для начала условимся — в этой статье мы создадим механику сбора монеток, которые не кладутся в инвентарь, а просто отмечаются в интерфейсе. Давайте начнем. Прежде всего нужно создать сам объект монетки — в виде префаба. В Hierarchy нажимаем правой кнопкой мыши и выбираем пункт 3D Objects. В появившемся меню выбираем Sphere. Далее меняем параметр Scale этой сферы на следующие:
- X — 0,25
- Y — 0,25
- Z — 0,01
Таким образом мы сделаем сферу похожей на тонкую монетку.
Далее необходимо монетку раскидать по уровню в удобном вам порядке. Следующим пунктом, необходимо к префабу монетки в инспекторе добавить тег. Назовем его PickUpCoins. После добавления тега на префаб, он автоматически применится ко всем копиям.
Создадим скрипт CoinCollector в нашем проекте и впишем в него следующие строки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public static float CollectCoins; //Считаем собранные монетки public Text AllCollectableCoins; //Общее количество монет на уровне private float AllCoinsStart; //Считаем все монетки находящиеся на уровне void Awake() { AllCoinsStart = GameObject.FindGameObjectsWithTag("PickUpCoins").Length; CollectCoins = 0; SetAllCollectableCoins(); CurrentCollectedCoins(); } void OnTriggerEnter(Collider other) { if (other.gameObject.CompareTag("PickUpCoins")) { other.gameObject.SetActive(false); CollectCoins = CollectCoins + 1; AllCoinsStart = AllCoinsStart - 1; SetAllCollectableCoins(); CurrentCollectedCoins(); } } |
Мы объявили 3 переменные CollectCoins, AllColectableCoins и AllCoinsStart. Первая переменная нужна для того, чтобы вести подсчет уже собранных монет, а вторая переменная нужна для того, чтобы отрисовать в интерфейсе количество монет на уровне, третья переменная для того, чтобы посчитать количество монет на уровне и сохранить это значение.
В методе Awake с помощью функции GameObject.FindGameObjectsWithTag(«PickUpCoins»).Length мы посчитали сколько монет находится на уровне. CollectCoins как полагается равно нулю. Так же имеются еще 2 метода, которые контролируют отрисовку интерфейса при изменении переменных, но о них чуть позже. В методе OnTriggerEnter (встроенный метод в Unity) мы объясняем что, если произошло столкновение с объектом имеющим тег PickUpCoins, то:
- other.gameObject.SetActive(false) — сделать монетку неактивной. Если более развернуто — сделать объект с тегом PickUpCoins неактивным.
- CollectCoins = CollectCoins + 1 — Количество текущих монет равно количество монет + 1 монета.
- AllCoinsStart = AllCoinsStart — 1 — каждый раз отнимаем одну монетку из общего числа монет на уровне.
- Ну и вызов систем отрисовки значений интерфейса.
Основная механика завершена, давайте поработаем с интерфейсом. Определимся с задачей. Мы хотим, чтобы при столкновении с монеткой, общее количество монет уменьшалось, а количество собранных монет росло. Логика для этого у нас есть и задатки управления интерфейсом тоже есть, но этого пока еще маловато. Добавим логику недостающую логику:
1 2 3 4 5 6 7 8 9 |
public void SetAllCollectableCoins() { AllCollectableCoins.text = AllCoinsStart.ToString(); } public void CurrentCollectedCoins() { CollectedCoins.text = CollectCoins.ToString(); } |
Обратим внимание что добавилась еще одна переменная, и в конечном итоге весь скрипт должен выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
public Text CollectedCoins; //Количество собранных монет public Text AllCollectableCoins; //Общее количество монет на уровне public static float CollectCoins; //Считаем собранные монетки private float AllCoinsStart; //Считаем все монетки находящиеся на уровне void Awake() { AllCoinsStart = GameObject.FindGameObjectsWithTag("PickUpCoins").Length; CollectCoins = 0; SetAllCollectableCoins(); CurrentCollectedCoins(); } void OnTriggerEnter(Collider other) { if (other.gameObject.CompareTag("PickUpCoins")) { other.gameObject.SetActive(false); CollectCoins = CollectCoins + 1; AllCoinsStart = AllCoinsStart - 1; SetAllCollectableCoins(); CurrentCollectedCoins(); } } public void SetAllCollectableCoins() { AllCollectableCoins.text = AllCoinsStart.ToString(); } public void CurrentCollectedCoins() { CollectedCoins.text = CollectCoins.ToString(); } |
Супер! Теперь этот скрипт кидаем на модель игрока, ведь именно он будет взаимодействовать с монетками и сталкиваться с ними.
Работа с интерфейсом
В инспекторе на модели игрока после прикрепления скрипта появились 2 строки, куда необходимо прикрепить текст с общих количеством монет и с количеством собираемых игроком монет.
После того как объекты прикреплены смотрим, что получилось:
Собственно как-то так. Это один из способов, думаю не самый лучший, но рабочий. Спасибо за внимание, на этом пожалуй все, очень надеюсь, что мы помогли вам в реализации ваших идей в Unity в части вопроса как сделать собираемые предметы. Если остались вопросы пишите их в комментариях. Не забывайте про нашу группу в ВК и YouTube канал.
Добрый день, использовал ваш скрипт( для сбора монет) и в Юнити выдало ошибку: Assets\CoinCollector.cs(32,1): error CS0106: The modifier ‘public’ is not valid for this item
Подскажите ,что делать?