Денис KaDR Калужин - Путь в разработку игр | Движуха Сакутина
606 subscribers
59 photos
6 videos
4 files
73 links
Разработка игр и поиск кузинатры))
По вопросам можно писать в лс @KaDR666
Download Telegram
Привет!
Пока без постов. Скоро релиз, поэтому мы с моим режимом такие😅:
😁19
👋Привет!
Я жив, не теряйте😁

Идей много, а времени мало)
Но чуток разобрался с делами и начинаю готовить новый пост.

Хочу попробовать новый формат, который прям огонь будет, как по мне🔥
На выходных постараюсь выложить.
Надеюсь, зайдёт))

Есть ещё одна бомбическая идея для нового цикла (нет, ЦИКЛИЩА) постов, но в производстве он затратен, как минимум, по времени, так что о нём расскажу когда буду уверен, что не надорвусь делать😅

Всех обнял🫂
👍20🤔6😁2❤‍🔥11🔥1🏆1😎1
Работа с событиями аниматора ч.1.

Привет!
Часто нам хочется синхронизировать логику игры с конкретной фазой анимации. Например, наносить урон противнику только в середине анимации удара. Тут есть несколько подходов.

Первый (костыльный, но прозрачный и относительно безопасный) - использование корутины, которая будет выполнять действие с задержкой.

⛔️Минусы очевидны:
1. надо вручную подбирать время задержки;
2. если изменить скорость воспроизведения анимации, придется снова вернуться к п. 1.

Его не рассматриваем, тк тут и так все понятно.

Второй - использование событий анимации.

Он лишен минусов первого способа. Зато имеет свои.
Но пока разберемся, как они работают.

Тут, на самом деле, все просто.
(Видео инструкция)
1.Открываем окно аниматора (ctrl + 6 или через меню Window).
2. Выбираем анимацию.
3. Находим нужный кадр.
4. Через ПКМ под таймлайном добавляем ключ события.
5. Выделяем этот ключ и в окне инспектора видим выпадающий список, где можно назначить метод-обработчик.

Собственно, все.

⛔️Основные минусы данного способа:
1. Компонент с методом-обработчиком должен висеть на том же объекте что и аниматор (что противоречит подходу, при котором мы стараемся сосредоточить скрипты на верхнем объекте иерархии, а его визуальное представление делаем дочерним к нему)
2. Отсутствие прозрачности. По сути, мы упираемся в проблему, описанную в статье про назначение обработчиков событий из инспектора.

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

Однако, об этом в следующий раз.
👍235
This media is not supported in your browser
VIEW IN TELEGRAM
❗️⚡️🔥Обещанный новый формат🔥⚡️❗️

Работа с  событиями аниматора ч.1. (доп.)

Не знаю, как часто получится такое делать, но, по возможности, буду делать сопровождение или дополнение к статьям)
👍31🔥42
🎄🐉🐲С новым годом!🐲🐉🎄

Всех с наступающим, товарищи программисты, геймдеверы и сочувствующие!))

Желаю всем карьерного и профессионального роста и прибыльных проектов в новом году!

Ну, и, по классике, крепкого здоровья чтобы вытянуть такое количество кода 😁
🎄229🔥4🥰1🎉1
Работа с событиями аниматора ч.2.

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

Задача

Напомню. Нам хочется иметь возможность:
1. хранить аниматор и компоненты с бизнес логикой на разных объектах;
2. средствами IDE отследить, где используются события аниматора.

💼Дано

Объект игрока со структурой как в этой статье:
— Сам объект, хранящий компоненты с логикой
—— Дочерний объект - представление (модель/визуал), тут же живет и аниматор.
—— Возможно, какие-то еще дочерние объекты.

Решение

1. Создаем прокси-компонент, который будет висеть рядом с аниматором, как показано в прошлой части. Основная задача этого компонента - перенаправить событие аниматора подписчикам через обычные события.

Например:
class PlayerAnimationEvents : MonoBehaviour
{
public event Action Attacking;

public void InvokeAttackingEvent() => Attacking?.Invoke();
}


На событие аниматора в инспекторе подписываем метод InvokeAttackingEvent.

2. Добавляем ссылку на этот компонент в классы, где необходимо реагировать на события аниматора и осуществляем там подписку на прокси события.

public class Player : MonoBehaviour
{
[SerializeField] private PlayerAnimationEvents _animationEvents;
[SerializeField] private Attacker _attacker;

private void OnEnable() => _animationEvents.Attacking += _attacker.Attack;
private void OnDisable() => _animationEvents.Attacking -= _attacker.Attack;
}


Итог

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

Проблема

Единственная проблема, которую мы не можем тут решить - необходимость подписки на события самого аниматора из инспектора из-за чего они сломаются при смене имени метода или сбое в проекте. Но это уже мелочи и сильно лучше того что было ранее)
👍16🔥21
Как запускать корутины из не MonoBehaviour класса

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

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

Плохая новость — нам все ровно потребуется MonoBehaviour.
Хорошая — это не обязан быть сам класс, в котором мы работаем. Достаточно прокинуть через конструктор объект наследующий MonoBehaviour и пользоваться его методами.

Проблема

Передавая в класс объект наследующий MonoBehaviour как он есть, то мы предоставляем доступ вообще ко всем его методам. В том числе, никто не мешает нам его удалить и тем самым убить все корутины, которые через него запущены.

Решение

Самым распространенным решением является создание интерфейса, который бы описывал только методы, отвечающие за работу с корутинами:

public interface ICoroutineRunner
{
Coroutine StartCoroutine(IEnumerator coroutine);
void StopCoroutine(IEnumerator routine);
}


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

public class CoroutineRunner : MonoBehaviour, ICoroutineRunner { }


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

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

public class Spawner 
{
private readonly ICoroutineRunner _coroutineRunner;
private Enemy _prefab;

public Spawner(Enemy prefab, ICoroutineRunner coroutineRunner)
{
_prefab = prefab;
_coroutineRunner = coroutineRunner;
}

public void StartSpawn()
{
_coroutineRunner.StartCoroutine(Spawn());
}

private IEnumerator Spawn()
{
//spawn
}
}


⚠️Важный момент
Если раньше вы могли полагаться на остановку корутины вместе с уничтожением объекта, который ее запустил, теперь необходимо следить за запущенными задачами и вручную их останавливать, если они больше не нужны (подробнее тут).
Особенно это актуально, если CoroutineRunner существует не в рамках отдельной сцены, а один на весь проект.

#полезныесоветы
👍8🔥3
Контролируемая случайность

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

И да, и нет.

В жизни мы часто сталкиваемся с ситуациями, где результат зависит не только от наших усилий, но и от случайности. Однако случайность — это не всегда хаос, который невозможно контролировать. Напротив, её можно использовать как инструмент для достижения успеха. Этот подход называется контролируемой случайностью.

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

Представьте, что нам нужно бросить монету так, чтобы она выпала орлом вверх. Какова вероятность, что этот получится сделать с первого броска? 50/50. А если будет 100 попыток и достаточно, чтоб орёл выпал хотя бы раз? Успех почти гарантирован! Понимаете?

Конечно, жизнь — это не лотерея и вероятность успеха каждой попытки сильно меньше 50%, но принцип остаётся тем же.

Накопительный эффект

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

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

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

Как строить жизнь, чтобы увеличить шансы на успех?

0. Делайте много попыток. Это самое главное.

1. Создавайте обстоятельства для благоприятствующие успеху. Ходите на конференции, заводите нужные знакомства, читайте и смотрите правильных авторов.

2. Копите опыт. Анализируйте свои ошибки (и успехи тоже), делайте выводы.

3. Автоматизируйте и оптимизируйте. Используйте накопленные знания и технические наработки для ускорения процессов.

4. Действуйте в одном направлении. Концентрация, например, на одном жанре позволяет глубже погрузиться в него и накопить больше опыта.

5. Примите случайность как часть процесса. Не бойтесь неудач и неожиданных результатов. Случайность — это не враг, а союзник, который может привести вас к новым возможностям.
🔥18❤‍🔥32🥱2👍1
Привет!

Хвастаюсь. Наконец, вышла в релиз игра над которой мы с командой работали перед НГ.

Наслаждайтесь)

Если хорошо себя покажет, будем развивать, идей уже куча😁

https://play.google.com/store/apps/details?id=survive.nuclear.desert
👍264👏1
Ребята, ещё раз всем спасибо огромное за фидбэк по игре! Очень приятно, что активно вкючились!
Работаем💪
👍125
🤓С чего начать работу в Unity🥸

Привет!

Недавно читал лекцию для новичков в разработке. Рассказал из чего состоит игра, какие задачи решает игровой движок и, главное, показал процесс создания первой игры.

Думаю "Чего добру зря пропадать" и решил поделиться с вами презентацией.

Для вас, скорее всего, нового там ничего не будет, но, может, вы знаете кому это отправить))
👍20
Гришаков вернулся, пришлось ехать в Москву)
👍8
Пока жду фото с Гришаковым покажу моего первого наставника в клубе и просто большого человека. Гроза Яндекс игр - Инди Алёша😁
🔥16👍41
Вот и фото с виновником подоспело)
👍17🔥5👎1🏆1👻1
Путь масштабирования студии

Привет!
Хочу поделиться с вами, на мой взгляд, одним из самых крутых слайдов из презентации.

С одной стороны, "секретного ингредиента нет", а с другой - почему-то самые простые вещи оказываются самыми сложными для понимания и поэтому их надо проговаривать.

Когда стартуем свой путь на рынке, имеет смысл держать в голове такую схему:

1. Сначала спамите простенькими проектами, как из пулемёта и смотрите статистику. Как только появился явный лидер - доводим его до ума.
2. Выкладываем ±завершённый продукт везде, до куда можем дотянуться
3. Сколько можем, улучшаем его путём бесконечных А/Б тестов.
4. Когда упираемся в потолок - начинаем закупать рекламу с горизонтом окупаемости ~ 2 месяцев.
5. Ну, и когда доход позволяет - расширяем штат, чтоб вести больше проектов одновременно.

Естественно, в жизни всё чуть сложнее, чем на бумаге, но как ориентир - схема очень крутая.
👍14🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Следующая статья идет тяжеловато из-за нехватки времени, но лучшей подводки к ней вы не увидите🤣🤣🤣
😁14🔥3👍1🌭1
Был программистом, стал (техническим) должником

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

Технический долг — это метафора, которая описывает последствия принятия краткосрочных решений в разработке, которые упрощают или ускоряют процесс в краткосрочной перспективе, но приводят к дополнительным затратам в будущем. Часто такие решения принимаются из-за отсутствия опыта (не понимаете в чем проблема или не знаете как лучше).


Это как "долг", который нужно "погасить", чтобы поддерживать и развивать проект, пока не накапали проценты (а капают они с каждым комитом).

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

Что ведёт к накоплению технического долга?

1. Сжатые сроки
Когда разработчики вынуждены быстро выпускать игру или её части, они могут пропускать важные этапы, такие как рефакторинг, тестирование или оптимизацию.

2. Отсутствие документации (в основном автодокументирования и соблюдения нотации)
Другим разработчикам (или даже самому автору) часто сложно понять, как работает код, если он написан не по нотации. Это замедляет дальнейшую разработку и увеличивает риск ошибок. Кроме того, другие разработчики могут повторно реализовать тот же функционал, тк не знают/не понимают, что кто-то уже это сделал или не могут найти.

3. Использование "костылей" (нет ничего более постоянного, чем временное)
Временные решения, которые быстро решают проблему, но не являются оптимальными, часто становятся частью кода. Со временем такие "костыли" накапливаются и усложняют поддержку.

4. Недостаточное тестирование
Если не писать unit-тесты или не проводить достаточное тестирование, ошибки могут оставаться незамеченными. Это приводит к тому, что их приходится исправлять позже, что увеличивает затраты (тк за проблемный код могут цепляться будущие решения).

5. Игнорирование архитектуры
Если не уделять внимание проектированию архитектуры игры, код может стать запутанным и сложным для поддержки. Например, сильная связанность компонентов или отсутствие модульности.

6. Частые изменения требований
Если требования к игре часто меняются, разработчики могут вносить изменения в код "на скорую руку", что приводит к накоплению долга.

7. Неоптимизированные ассеты
Использование тяжелых ассетов (например, высокополигональных моделей или текстур высокого разрешения) без оптимизации может привести к проблемам с производительностью, которые придется решать позже.

8. Отсутствие рефакторинга
Если код не рефакторить (не улучшать его структуру и читаемость), он становится всё более сложным для понимания и поддержки. Написание идеального кода сразу (особенно в коменде) - утопия.

9. Использование устаревших подходов
Unity постоянно развивается, и некоторые методы или API могут устаревать. Если не обновлять код, это может привести к проблемам совместимости и производительности.

10. Недостаток опыта команды
Если разработчики недостаточно опытны, они могут принимать неоптимальные решения, которые в будущем придется переделывать.

Неутешительный итог

Технический долг коварен, многолик и неотвратим. Победить его полностью в реальном проекте невозможно. Все что нам остается - сдерживать эту критическую массу костылей как можно дольше, пока проект не развалится под их тяжестью. Но это не повод не пытаться. При должном усердии и дисциплине проект может существовать десятки лет (правда, на втором десятке он, скорее всего, уже будет напоминать паралитика на ИВЛ, зато живой 😅)

В будущих статьях рассмотрим несколько примеров (в том числе тот, с которым я недавно столкнулся и который побудил меня написать этот цикл).
👍14🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Привет!
По классике, живой и в запаре)
Времени на статью небыло, поэтому буду хвалиться репетициями в театре😁
🔥17😁3
Forwarded from в IT и выйти
⚡️В России запретили КОПИПАСТ — соответствующий законопроект уже внесён в Госдуму. Теперь разработчикам запрещено копировать код, даже свой. Каждый новый проект должен писаться с нуля, иначе штраф.

Эксперты предупреждают: следующим могут запретить копипаст в Telegram. Если примут закон, админы каналов будут вынуждены писать посты сами.

Испугались? С 1 апреля, дорогие подписчики 🥰

@techmedia
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣25😁8🎉3
Как тестировать игры на Android

Привет!
Прошу прощения за долгое отсутствие — был занят делами насущными, но чтоб разбавить немного информационный вакуум, делюсь полезным гайдом.

Сегодня разберём, как удобно тестировать игры на Android, используя Unity Remote 5. Это приложение значительно ускоряет процесс проверки изменений в проекте. Оно транслирует изображение из редактора в смартфон и позволяет производить тест без сборки .apk. Инструмент мега полезный, но многие даже не подозревают о его существовании.

Подготовка

1. Активация режима разработчика и отладки по USB
Для начала нужно включить режим разработчика на смартфоне.

На Xiaomi:
- Откройте «Настройки» → «О телефоне».
- Тапайте 7 раз по пункту «Версия MIUI», пока не появится уведомление «Вы стали разработчиком».
- Вернитесь в настройки, зайдите в «Расширенные настройки» → «Для разработчиков».
- Активируйте «Режим разработчика» и ниже включите «Отладка по USB».

На других устройствах процесс похож: обычно нужно найти раздел «О телефоне», несколько раз нажать на «Номер сборки», затем включить отладку в меню разработчика.


2. Установка Unity Remote 5
Скачайте приложение из Google Play.

Если запустите его — увидите окно с подсказкой:
«Подключите устройство к ПК по USB и нажмите PLAY в Unity.
Выберите устройство в: Edit → Project Settings → Editor»


3. Подключение телефона к компьютеру
Соедините смартфон с ПК через USB-кабель.
Если появится запрос «Разрешить отладку по USB?», нажмите «Разрешить» (или выберите «Передача данных», если такого пункта нет).

4. Настройка Unity
- Откройте File → Build Settings и убедитесь, что выбрана платформа Android. Если нет - переключите.
- Перейдите в Edit → Project Settings → Editor. В выпадающем списке «Device» выберите «Any Android Device».

5. Запуск тестирования
Нажмите Play в Unity — изображение с редактора должно появиться на экране телефона.
Теперь можно тестировать управление через тачи, интерфейс и другие элементы без сборки APK.

Готово!

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

Теперь у вас есть отличный инструмент для быстрой проверки изменений в проекте.
👍18🤔1