Джун Джуно к вашим услугам! Путь в разработку игр | Движуха Сакутина
前往频道在 Telegram
354
订阅者
-124 小时
-17 天
-530 天
帖子存档
🔥 АЛГОРИТМЫ 🔥
🙂 Всем привет! У нас начинается новая тема, которую мы до этого не встречали. Одна из самых главных составляющих программирования - алгоритмы
🗣️ Алгоритм - набор инструкций, необходимых для выполнения некоторой задачи 🗣️
❗️Любой фрагмент кода можно можно назвать алгоритмом, но мы будем разбирать более интересные
➕ Рассмотрим базовый набор алгоритмов любого разработчик. Большая часть алгоритмов уже реализована в нашем любимом C#. Но важно знать принцип работы и понимать их плюсы и минусы
➕ Научимся способу вычисления их сложности, называемый О-большое
➕ Углубимся в понятие рекурсии и научимся ее правильно использовать
📈 Если хотите эффективно изучать алгоритмы в C# - Джун Джуно к вашим услугам!
+1
🔥 ПАТТЕРН ВИЗИТЁР 🔥
🙂 Всем привет! Под конец июня приготовил вам долгожданный пост. Помните я вам обещал самый мощный паттерн для OCP? Время пришло! Время для визитора!
‼️ Ситуация:
📌 У нас есть инвентарь зелий с различными эффектами, все они хранятся под абстрактным классом Potion
📌 Нам нужно менять характеристики персонажа в зависимости от эффекта зелья
📌 Хранить ссылку на персонажа в каждом зелье нельзя, значит тот, кто обращается должен знать какое это зелье
💥 Решение:
1️⃣ Сделаем класс PotionUser, в который приходит объект типа Potion. Он через switch проверяет к какому типу относится данное зелье
🚫 Минусы данного подхода:
❌Если появится новый тип зелья придется вписывать в Switch новый блок
❌ Если тех, кто также использует Switch будет больше, то нужно следить за дописыванием блоков в каждом классе
2️⃣ В классе Potion сделать абстрактный метод Accept, получающий в аргумент IPotionVisitor. Теперь все наследники будут вызывать метод Visit у IPotionVisitor, передавая в аргумент самого себя
✔️ Плюсы данного подхода:
➕ Мы создаем инверсию управления. Не мы узнаем кто это, а класс сам говорит кто он
➕ Если нового метода Visit не существует, мы просто дописываем его в интерфейсе. И по появившимся ошибкам мы найдем все места где нужно его реализовать. К слову о силе контрактного программирования
📈 Подводя итоги, можно заметить, что мы больше не занимаемся модификаций старых классов, но при этом расширяем логику проекта. А если хотите научиться круто писать код - Джун Джуно к вашим услугам!
+1
🔥 Dependency Inversion Principle - финал SOLID🔥
🙂 Всем привет! Сегодня мы завершим цикл постов по изучению SOLID. Мы рассмотрим, наверное, самый сложный для понимания принцип
❗️ Принцип инверсии зависимостей звучит так:
🗣️ Модули нижнего уровня не должны завесить от модулей верхнего уровня 🗣️
⛔️ В исконной формулировки говориться, что оба модуля должны завесить от абстракции, но в таком случае весь код станет слишком абстрактным. Поэтому мы следуем этому правилу не так жестко!
☄️ Только нижние уровни зависят от абстракции
⁉️ Для начала разберемся, что значит верхние и нижние уровни?
📊 Градация идет по принципу специфичности. Рассмотрим на примере магазина с патронами:
1️⃣ Самым специфичным будет слой вью. Операции которые можно производить над магазином будут варьироваться от игры к игре.
2️⃣ Следующим идет слой модели. Каждая модель - хранилище определенных данных. Если появятся новые данные, мы создаем новые модели, а старые изменять не будем. Модели можно таскать из проекта в проект. Это будет органично вписываться в любой проект, в котором есть оружия
3️⃣ Самый неспецифичный слой - инфраструктурный. Это будет сервис, который сохраняет данные. Он может сохранять все. Такой класс может кочевать в любые игры
‼️ Таким образом, чем специфичнее модуль (класс или слой), тем он выше по уровню
💥 Теперь САМЫЙ СОК. Как это работает на практике:
➕Класс AmmoMagazineReloader перезаряжает оружие по нажатию кнопки и ссылается на AmmoMagazineModel
➕ Класс модели хранит у себя JsonSaveLoaderServise
➕ В данном случае классы верхнего уровня зависят от классов нижнего, что НЕ НАРУШАЕТ DIP
➡️ Теперь пойдем в обратную сторону
➕ Есть кнопка, которая вызывает загрузку данных. Значит сервис должен хранить список объектов, которым нужно передать загружаемые данные
➕ Теперь возникает ситуация, что класс нижнего уровня зависит от верхнего
➕ В таких случаях мы прячем классы верхнего уровня под интерфейс
➕ Теперь классы нижнего уровня зависят от абстракции
📈 Мы познакомились с пятью паттернами SOLID! Надеюсь, вам было интересно. Было вложено много сил, особенно в последний пост. Поэтому поставьте реакцию, мне будет очень приятно! Если ждете много новых постов про разработку игр - Джун Джуно к вашим услугам!
🔥 Джун Джуно теперь... дизайнер? 🔥
🙂 Всем привет! Давно я не выходил к вам на связь с разговорами о планах. Хочу поделиться с вами новостями, связанными с телеграмм каналом
‼️ Разочарую всех своих хейтеров и завистников, кто подумал, что я сдулся. Не дождетесь этого)
📈 Июнь стал важным месяцем для осознания дальнейшего пути развития и набора сил. Канал на YouTube так и не был запущен. Но было найдено немало талантливых ребят, кто примут участие в моих будущих проектах. Я не хочу кормить вас пустыми обещаниями, хочу чтобы вы увидели результат упорной работы своими глазами..
⚠️ Поэтому я приобрёл курс по графическому дизайну. Рекламировать ничего не буду, лишь скажу, что посоветовал мне его разбирающийся в теме человек
✔️ Цель моей деятельности - научить людей писать хороший код. Необходимо продвигать такой контент в массы, чтобы одержать победу над говнокодерами. И без отличной картинки - это будет невозможно
⭐️ Поэтому вы увидите рост качества постов! Не сомневайтесь в этом! Если интересно узнать больше про чистый код - Джун Джуно к вашим услугам!
🔥 ПАТТЕРН ПРОТОТИП 🔥
🙂 Всем привет! Сегодня был очень занят, поэтому пост вышел весьма маленьким
‼️ Рассмотрим проблему
💥 Очень часто в разработке возникает потребность копировать объекты, но появляется проблема с инициализацией нового объекта и дубляжом кода. Паттерн прототип решает подобные проблемы
⚡️ Рассмотрим суть паттерна на примере:
✔️ У нас есть несколько оружий скрытых под интерфейсом IGun. В нем есть метод Clone, который возвращает IGun. Соответственно все объекты, которые реализуют интерфейс, будут возвращать клоны самих себя
✔️ По итогу, мы скрываем логику копирования внутри другого класса пряча это под интерфейсом. Клиентам не придется вдаваться в подробности какой это конкретно класс и как его собирать
📈 Не забывайте ставить реакции. Это очень мотивирует меня выпускать больше постов! А если нужно больше информации про такие паттерны - Джун Джуно к вашим услугам!
🔥 ГЛАВНЫЙ УБИЙЦА ООП 🔥
🙂 Всем привет! Сегодня я хочу поговорить о статике. Узнаем почему плохо её использовать, но в каких случаях она оправдана
❗️Недостатки:
❌ Самый главный - частые и тяжело отслеживаемые NullRefException. Жизнь ссылок невозможно контролировать
❌ Статический объект живет всю игровую сессию. Это значит, что даже на новой сцене ссылка будет жить
❌ Невозможно контролировать порядок инициализации и уничтожения статических объектов
❌ У статических очень тяжелый контроль состояний этого объекта
ℹ️ В общем и целом всё то, что мы любим в ООП не работает при использовании статики. Но она очень помогает в функциональном программировании
❗️ Плюсы:
➕ Если сделать статический класс со статическим методом, который просто производит математические операции, то это сразу становится очень удобным. У метода есть вход и выход, без какой-либо ООП составляющей
➕ Также статика, помогает при хранение статических параметров. Например для строк: Input.Axis или запуска анимаций через код
⚠️ Не забывайте ставить реакции под постами. Если интересно больше постов про ООП - Джун Джуно к вашим услугам!
+2
🔥 ВИДЫ СВЯЗЕЙ В ООП 🔥
🙂 Всем привет! Сегодня я хочу поговорить о том, как классы могут связываться друг с другом
‼️ Существует два вида связей: is-are(иметь) и has-are(являться)
📌 Связь has-are реализуется путем наследования. Например, отношение класса Dog к классу Animal. Мы уже рассматривали наследование, поэтому не будем особо заострять внимание
📌 Связь is-are имеет уже два варианта реализации: композиция и агрегация
❗️ Общая черта:
➕ Один объект является частью другого. Например, есть класс Car, но машина не может работать без двигателя. Поэтому он хранит в своем поле класс Engine. В данном случае двигатель это часть машины
💬 Различия:
➕ Композиция. Инициализация двигателя происходит внутри класса машины. То есть, двигатель проживет ровно столько, сколько проживет машина. Никто больше не ссылается на этот двигатель и он является неотъемлемой частью этой машины
➕ Агрегация. Инициализация двигателя происходит извне. Это значит, двигатель создается где-то во вне и передается в машину через метод или конструктор. Данный подход работает, когда мы хотим передать интерфейс объекта
📈 Итоги. Если вы хотите связать два класса, то подумайте - класс B является только составной частью класса A или он полностью относится к нему, конкретизируя тип предка
⚠️ Хотите узнать больше про ООП? - Джун Джуно к вашим услугам!
+2
🔥 ПАТТЕРН - BUILDER 🔥
🙂 Всем привет! Даже находясь в Санкт-Петербурге, я не забываю про вас!
👀 Поэтому сегодня мы поговорим о простом, но достаточно полезном паттерне - Builder
⚡️ Его суть заключается в настройке объекта путем вызова его методов. Нам не важен порядок и количество вызываемых методов, объект сконструируется в любом случае
‼️ Есть два вида данного паттерн:
1️⃣ Есть строительные методы, которые ничего не возвращают. И один метод, возвращающий собранный объект. Этот способ работает в паре с абстрактными строительными методами. Это очень помогает, когда есть разные стратегии постройки объекта
2️⃣ Каждый из методов имеет возвращаемый тип и возвращает он сам себя. Нам не нужно вызывать разные методы, обращаясь к переменной или полю. Можно вызывать методы друг за другом через точку. Это визуально улучшает код. Также можно расположить в новую строчку каждый вызов. Удаляя вызов любого метода ничего не сломается
⚠️ Обратим внимание! Как пример для первого способа я использовал LINQ. Набираем десять лайков и пишу пост о том, что это и как его использовать
❗️ А если нужно больше паттернов - Джун Джуно к вашим услугам!
⚠️ P.S. Ну и если я какой-то текст дочитываю до конца, то никогда не поленюсь поставить лайк и в комменте написать что-то типа: "Братан, хорош, давай, давай, вперёд! Контент в кайф, можно ещё? Вообще красавчик! Можно вот этого вот почаще?"
🔥 Interface segregation principle 🔥
🙂 Всем привет! Ну вот и четвёртый принцип SOLID - самый простой и легкий в понимании. При этом его соблюдение делает код намного чище
‼️ Если обобщать, то данный принцип говорит о том, что не нужно давать больше чем от нас требуется. Достигается это путем ограничения класса интерфейсами
⚡️ Пример:
📌 У нас есть класс Gun и класс BulletsVisualizer. По-сути, классу визуализации не нужно знать и обращаться к методам и свойствам оружия. Все что ему нужно - это одно событие об изменении текущего числа патронов и свойство с их максимальным числом в обойме
❌ Как и у любого другого принцип - у этого есть обратная сторона. Когда мы все разбиваем на тысячи интерфейсов - это только мешает клиентам этих классов
📈 Впереди нас ждет последний принцип. Как по мне он самый сложный для понимания, поэтому готовьтесь!
⚠️ Напомню, осталось всего пару лайков для выхода поста про крутеший паттерн. Не забываем ставить реакции!!
👀 А если понадобится помощь - Джун Джуно к вашим услугам!
🔥 За этими воротами спасается российский GameDev 🔥
🙂 Всем огромный привет из культурной столицы России! Я сегодня приехал на пару дней в Санкт-Петербург
⁉️Что должен сделать первым делом любой разработчик игр, приехав в центр города?
❌ Неправы те, кто подумал о посещении Казанского собора или Эрмитажа
✔️ Настоящие программисту посетят офис игровой студии "АГАВА", детище Романа Сакутина
👀 К сожалению, внутрь двора мне не удалось зайти... Но фотографию на память должен был сделать
⚠️ Не знаете, что посмотреть в незнакомом городе? Джун Джуно к вашим услугам!
🔥 LISKOV SUBTITUTION PRINCIPLE 🔥
🙂 Сегодня мы рассмотрим третий принцип SOLID. Данный принцип помогает соблюдать чистоту при наследовании. Код становится понятнее и очевиднее
‼️ На самом деле мы уже соблюдали принцип подставки не зная об этом. Шаблонный метод - главный паттерн помогающий ему следовать
✔️ В качестве примера, мы возьмем тот же LazerGun и унаследованный от него LuzerAutomate. Наследник переопределяет метод Shoot. Тем самым заменяя одиночную стрельбу на очередь имеющую разброс
✔️ Если присмотреться, то можно заметить главное. Мы создаем инверсию управления. То есть не наследник вызывает метод абстрактного класса, а наоборот. Также стоит заметить, что наследник не ломает логику базового класса
📈 Резюмируя LSP говорит: если вы от чего-то наследуетесь, вы можете что-то переопределить, но вы этим переопределением не должны ломать контракт базового класса. Это можно проверить путем написания тестов для базового класса. Если наследники тоже проходят все тесты - значит LSP соблюдается
⚡️СТАВИМ 15 ЛАЙКОВ - я выпускаю пост, как писать тесты в Unity! Хотите стать крутым программистом? - Джун Джуно к вашим услугам
🔥 АНТИ OCP - ЗНАЙ МЕРУ АБСТРАКЦИИ 🔥
🙂 Сегодня небольшой пост про то, как перестараться с закрытостью или открытостью
‼️ Список ошибок:
1️⃣ Если вы сделаете общение между двумя конкретными классам на событиях. Может показаться, что вы защищаете класс метод от нежелательного вызова, но это все усложнит
2️⃣ Делать фабрику фабрик для фабрик. Слишком много абстракций путает
3️⃣ Создавать много цепей наследования. Чем больше связей через наследование, тем сложнее это рефакторить
4️⃣ Прятать все классы под
интерфейсом. Это очень сильно усложняет чтение кода
❗️ Старайтесь чувствовать грань: где нужно оставлять место для расширения, а где не стоит. Если возникают вопросы, задавайте их, потому что Джун Джуно к вашим услугам!
🔥 Open-Close Principal 🔥
🙂Всем привет! Сегодня обсудим второй принцип SOLID
⚡️ Принцип открытости-закрытости. В интернете можете увидеть различную трактовку этого принципа, но я раскрою в наиболее понятной форме
🗣️Класс должен быть открыт для расширения, но закрыт для модификации🗣️
❗️ Начнем с части про закрытость:
✔️ Если есть стабильный класс, со стабильным интерфейсом (публичными членами), то мы не должны дописывать в нем что-то в случае обновления игры. Потому что у этого класса может быть большое количество пользователей. Любая модификация может навредить им
⁉️ Как нам безопасно обновлять игру?
✔️ Мы уже изучили решения в постах про стратегию, шаблонный метод и фабрику. Есть еще несколько паттернов обеспечивающие соблюдение OCP. Мы обязательно их рассмотрим в будущих постах
‼️ Если конкретно говорить про понятие открытости:
✔️ Намеренное создание зазоров в коде. Позволяет менять изменяющиеся части без негативных последствий . Достигается это путем переопределения методов, сокрытие под интерфейсом классов или обобщением типов (generics). О том что такое generics мы тоже обязательно поговорим в будущем
📈 Набираем 15 пальцев вверх и я пишу пост про паттерн Visitor - САМЫЙ МОЩНЫЙ паттерн обеспечивающий OCP. Ведь всегда - ДЖУН ДЖУНО К ВАШИМ УСЛУГАМ
🔥 Single Responsibility Principal 🔥
🙂 Всем привет! Сегодня мы поговорим про первый принцип SOLID - SRP
✔️ Мы уже знаем, что всё в объектно-ориентированное программирование является объектами. Данный принцип говорит о том, что один объект должен отвечать только за что-то одно
⚡️ Частая история у новичков и не только:
📌 Написать GameManager, в котором может происходить что угодно. Он отвечает одновременно и за всё, и ни за что. Это и есть нарушение SRP
📌 Допустим у нас есть метод Shoot. В нем может происходить:
➕Создание патронов
➕Логика выстрела
➕Перезарядка оружия
➕Визуализация патронов в UI
⁉️ Чем чревато нарушение SRP?
🚫 Чем больше ответственностей в одном классе, тем тяжелее контролировать кучу состояний одновременно. Мы уже решали подобную проблему когда говорили об инкапсуляции
🚫 Если метод производит сразу несколько действий:
❌ Будет возникать дубляж кода. Очень частая история когда приходится копировать часть другого метода, если заранее об это не подумать
❌ Не получится подменять шаги алгоритма - переопределять методы. Как мы это делали в паттерне шаблонный метод
❌ Если мы захотим модифицировать одно из действий или исправить баг - можем случайно сломать другую механику, которая находится в этом же методе
‼️Несколько ред флагов, на которые стоит обращать внимание:
1️⃣ Если класс хочется назвать Manager или Controller. В таких случаях старайтесь декомпозировать класс на более мелкие
2️⃣ Если метод не влезать полностью в экран и выходит за его пределы. Значит, скорее всего, стоит сделать мини-методы для этого метода
3️⃣ Если хочется разделить публичные и приватные методы в рамках одного класса на группы и подгруппы
4️⃣ Также это касается и полей. Если хочется поделить поля на логические группы, значить стоит разбить на несколько классов
📈 В следующем посте я хочу рассказать про анти-SRP. Если вам интересно узнать где, заканчивается грань добра и зла - ПОСТАВЬТЕ РЕАКЦИЮ. Всегда помните - ДЖУН ДЖУНО К ВАШИМ УСЛУГАМ!
🔥 ЗАКРЫТИЕ NOOB SHOOTER 🔥
🙂 Всем привет! Давно не было постов про мой нынешний путь в разработке игр. Начну со свежей новости - игра, которую мы разрабатывали четыре месяца, закрывается
📉 Причиной для этого были недостаточные метрики. Игра не смогла принести желаемую прибыль и аудиторию
⛔️ У игры был сложный путь разработки. Сроки релиза переносились, нужно было время для адаптации всех членов команды
‼️ Но расстраиваться явно не стоит!
⭐️ У нас начнётся работа над новой игрой, к которой мы приступим с новыми силами! Если вам интересно погрузится в мир IT - Джун Джуно к вашим услугам!
🔥 СОКРАЛЬНЫЙ СМЫСЛ SOLID 🔥
🙂 Как часто вы слышали аббревиатуру SOLID? Если слышали и вас это заинтересовала, то скорее всего вы пошли в интернет, чтобы узнать его смысл. Везде пытаются объяснить разными способами, поэтому я постараюсь по-своему пояснить за каждый принцип
‼️ Для тех кто не в теме. SOLID это пять принципов объектно-ориентированного программирования. Сформулировал их Роберт Мартин, также известный, как дядюшка Боб. Также он написал очень много трудов по паттернам проектирования и чистому коду
⚡️ Расшифровка SOLID:
✔️ Single responsibility (SRP) - Принцип единой ответственности
✔️Open–closed (OCP) - Принцип открытости-закрытости
✔️Liskov substitution (LSP) - Принцип подстановки Лисков
✔️Interface segregation (ISP) - Принцип разделения интерфейсов
✔️Dependency inversion (DIP) - Принцип инверсии зависимостей
📈 Мы рассмотрим каждый принцип в отдельных постах и я попытаюсь максимально объяснить их сакральный смысл и пользу
⚠️ Если вам интересна эта тема или вы не понимаете хотя бы один из принципов - ПОСТАВЬТЕ РЕАКЦИЮ и напишите в комментариях смысл какого принципа вам не понятен. Хотите стать гуру в теме SOLID? ДЖУН ДЖУНО К ВАШИМ УСЛУГАМ!
+2
🔥 ИНКАПСУЛЯЦИЯ LIST В СВОЙСТВЕ КЛАССА 🔥
🙂 Часто бывает, что нам нужно переделать вовне список объектов, хранящихся в поле. Новички думают, что если сделать свойство с приватным сетором, то этот список защищен. Но это большое заблуждение
‼️ Рассмотрим ситуацию:
✔️ У нас есть класс Squad хранящий в себе юнитов. И есть класс SquadHealthView показывающий общее здоровье отряда
📈 Возможные решения от худшего к лучшему:
3️⃣ Сделаем публичное свойство которое ссылается на поле со списком юнитов. Из-за того, что список - это ссылочный тип, пользователи класса Squad копируют ссылку на этот список, а не его значения. Получается если кто-то сохранит у себя эту ссылку, а потом добавит или уберет объект из этого списка, то изменения коснутся и приватного поля класса Squad. Подобная ситуация создаст большую путаницу и много багов
2️⃣ Все коллекции реализуют интерфейс IEnumerable<T>. Соответственно свойство тоже может иметь тип IEnumerable<Unit>, которое ссылается на поле с юнитами. Пользователю этого свойства придется создать новый список в конструктор передать IEnumerable. Тем самым он сам скопирует всех юнитов. Но юниты классы, а классы это тоже ссылочный тип
1️⃣ Мы также прячем список под интерфейсом. Юнитов мы тоже прячем под интерфейсом IUnitReadOnly. Этот интерфейс будет передавать только свойства класса без его методов. Тем самым мы максимально защищаем класс Squad
💥 Подводя итоге, можно сказать:
👀 Мы обезопасили класс отряда, от неявного изменения состояния
Мы не перегружаем пользователей свойства информацией или функционалом, который им не нужен
⚠️ Если вы открыли для себя что-то новое и интересное - ПОСТАВЬТЕ РЕАКЦИЮ ПОД ПОСТОМ. А если вам нужно еще больше таких фишек - ДЖУН ДЖУНО К ВАШИМ УСЛУГАМ
🔥 ОЧЕРЕДЬ В С# 🔥
🙂 Многие знакомы с коллекцией List в C#. Но мало кто знаком и использует коллекцию Queue(очередь)
‼️ Ситуация:
📌 Допустим, у нас есть класс Squad, отдающий приказы свободным юнитам, которые хранятся в поле _units типа List<Unit>. Когда приказ отдан - Squad убирает юнита из списка. Когда приказ выполнен - юнит возвращается в список
🚫 Тут появляется неочевидная проблема!
❓ Что будет если юнит A, стоявший в начале списка, выполнит приказ раньше, чем юнит B, стоявший в конце списка, получит свой?
❌ Следующий полученный приказ будет выполнять опять юнит A. Таким образом юнит B может простоять на месте всю игру. Визуально это выглядит не очень.
⚡️ На помощь к нам придёт очередь
❗️Смысл данной коллекции в двух основных методах:
✔️ Enqueue - добавление объекта в очередь
✔️ Dequeue - получение объекта из очереди
✔️ Принцип работы: тот, кто первее войдет в очередь через метод Enqueue, тот раньше и выйдет из очереди через метод Dequeue
✔️В итоге, тот, кто первый выполнит приказ, тот получит следующий в последнюю очередь
✔️ Тем самым мы в равной степени нагружаем каждого юнита и никто не простаивает
📈 В следующем посте мы рассмотрим паттерн, который оптимизирует создание объектов через фабрику, используя очередь
💥 Если вам интересна реализация - ПОСТАВЬТЕ РЕАКЦИЮ ПОД ПОСТОМ. ДЖУН ДЖУНА К ВАШИМ УСЛУГАМ!
🔥 ПАТТЕРН POOL 🔥
🙂 Оптимизация - важная деталь в разработке игр. Игрок должен испытывать положительный опыт во время игры, который невозможно почувствовать, если количество FPS в игре не больше 20...
⚡️ Именно поэтому сегодня мы рассмотрим паттерн, который идет рука об руку с фабрикой
‼️ Обсудим предыдущий пример, у которого были недочёты
❌ Каждый раз, когда нам нужна была пуля, мы просто создавали новую, а старые бесконечно продолжали лететь вперед
❌ Но представим, если бы мы уничтожали старые пули - это тоже очень сильно било по оптимизации. Чтобы создать объект и уничтожить его тратятся большие ресурсы
⁉️ Как же выйти из этой ситуации?
✔️Хорошее решение в данном случае заранее создать некоторое количество пуль
✔️Если выпушенная пуля куда-то попала или улетела достаточно далеко - мы ее просто выключаем и телепортируем в место выстрела
✔️ И так несколько пуль по очереди будут выстреливать из оружия
📈 В итоге мы очень сильно сократим потребление ресурсов и сделаем игрока довольным!
👀 Если вы хотите еще больше лайфхаков по оптимизации игры - СТАВЬТЕ РЕАКЦИИ ПОД ПОСТОМ. ДЖУН ДЖУНО К ВАШИМ УСЛУГАМ
+4
🔥ЗАПУСК АНИМАЦИЙ ИЗ КОДА🔥
🙂 Всем привет! Мы уже успели рассмотреть как настраивать анимации в Аниматоре
👀 Сегодня мы рассмотрим переключение анимаций при помощи кода. В качестве примера мы будем запускать анимацию смерти
⁉️ Но как это сделать?
✔️Чтобы запустить анимацию смерти, создаем стрелочку от Idle к Dead
✔️ В левом верхнем углу окна Animator выбираем вкладку Parameters
✔️ Наживаем кнопку + и выбираем вкладку Trigger, называя триггер по смыслу. В данном случае Die
✔️ Кликаем на стрелочку от Idle к Dead. В поле Conditions нажимаем + и выбираем нужный триггер
✔️ Ну и чтобы анимация не была цикличный выключаем галочку Loop Time
‼️ Все приготовления закончены, можно приступать к коду
📌 Создаем класс CharacterAnimation и константу, которая должна обладать таким же названием, как и триггер
📌 Сереильзуемое поле, для компонента Animator
📌 В Update, при нажатии клавиши D в аниматоре вызываем метод SetTrigger, передавая в аргументы константу
💥 ВСЕ ГОТОВО, МОЖНО ЗАПУСКАТЬ И ТЕСТИРОВАТЬ!
⭐️Пост получился очень подробный в области настройки аниматора. Если вам было познавательно и интересно ставьте реакции под постом => 🔥, чтобы я понимал вашу заинтересованность)
⚠️ Хотите больше контента по разработке игр? Джун Джуно к вашим услугам!
