TGViewer
Channel Public Channel
SpellSinger - разработчик игр на Unity

SpellSinger - разработчик игр на Unity

@spellsingergames

Привет! Я Денис и я делаю игры на Unity. В этом блоге я делюсь своим опытом в геймдеве и не только.

Навигация в закрепе: https://t.me/spellsingergames/3

Написать в личку: @sinedsem
Subscribers
548
Photos
90
Videos
22
Links
105

Showing posts older than #134 · Back to latest

Older Posts 20 shown
Post #133 957
Канал по Бурить-Копать!

Мы завели канал по игре Бурить-Копать! Новости, девлоги, картинки, весь контент, ориентированный на игроков, будет там.

Приглашаем вступить: https://t.me/drill_and_dig

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

#бурить_копать
Telegram Игра Бурить-Копать! (Drill and Dig!) Разрабатываем казуалку-таймкиллер-рогалик про бур. Выходим в VK Play, Steam, Яндекс Игры, мобильные, все консоли и другие веб площадки. Наша студия Honeycombs Games.
  • 🔥 6
  • 💅 1
Post #132 905
Про подписи APK/AAB Android-приложений

Узнать, что такое подписи.

Два важных момента, которые помогли бы мне избежать проблем, если бы я знал их заранее. Рассказываю на примере RuStore, т. к. в Google Play ещё не выкладывался, но думаю там то же самое.

1️⃣ Если вы не создавали свою подпись, значит вы пользуетесь debug подписью от Unity.

Её можно достать и использовать в дальнейшем, например, если вы решите начать загружать в стор AAB вместо APK. Keystore находится в папке C:\Users\username\.android\debug.keystore, ключ называется androiddebugkey, а пароль от кейстора и от ключа - android. Насколько я понимаю, этот ключ создает Unity рандомно, так что можно продолжать использовать его и дальше.

2️⃣При загрузке в RuStore вы подписываете AAB с помощью upload_key, а потом RuStore делает из него APK и подписывает его с помощью key.

Я очень долго не мог понять, почему я не могу обновить приложение, установленное из RuStore, билдом, собранным в Unity. Фишка в том, что при загрузке AAB в RuStore используется два ключа. Одним ты подписываешь ABB (upload_key), а другой ты загружаешь в RuStore (key, упакованный с помощью PEPK).

Причем в документации RuStore этот upload_key, так же, как и процесс подписания AAB, упоминается только на этой странице, и не в тексте, а вот в этом видео.

Я пытался подписывать APK с помощью upload_key, хотя надо было использовать просто key.

#android #rustore #google_play #тайные_знания
  • 🔥 2
  • ❤ 1
  • 👍 1
Post #131 914
Автоматическая сборка билдов под разные платформы и площадки

Как обычно, кратко описываю суть, подробности спрашивайте в комментах.

1️⃣ На каждую площадку и тип сборки я сделал по отдельной кнопки в меню:
[MenuItem("Build/Yandex")]
public static void BuildYandex()
{
BuildYandex(BuildOptions.None);
}

[MenuItem("Build/Yandex [Dev]")]
public static void BuildYandexDev()
{
BuildYandex(BuildOptions.Development);
}


2️⃣ Есть основной метод Build, который непосредственно запускает сборку в Unity.
var buildPlayerOptions = new BuildPlayerOptions
{
scenes = new[] { "Assets/Scenes/Initialization Scene.unity" },
locationPathName = locationPathName,
target = buildTarget,
options = BuildOptions.CompressWithLz4 | buildOptions,
extraScriptingDefines = extraScriptingDefines.ToArray()
};

var report = BuildPipeline.BuildPlayer(buildPlayerOptions)


В него передаются параметры сборки, специфичные для каждой площадки. Например:
private static void BuildYandex(BuildOptions buildOptions)
{
Build(PlatformType.Yandex, new List<string> { "PLATFORM_YANDEX" }, BuildTarget.WebGL, "Build/Yandex", buildOptions);
}

Здесь
▶️ PlatformType.Yandex – это мой enum со всеми площадками
▶️ new List<string> { "PLATFORM_YANDEX" } – это Scripting Define, в эту штуку я оборачиваю код, специфичный только для Яндекса ( ещё могу передать SHOWCASE – код для шоукейсов)
▶️ BuildTarget.WebGL – непосредственно платформа
▶️ "Build/Yandex" – целевая папка для билда
▶️ buildOptions – необходимые опции, например Development

3️⃣ Есть класс с конфигами для каждой платформы
[Serializable]
public class PlatformConfig
{
[field: SerializeField] public string ProductName { get; private set; } = "drill_and_dig";
[field: SerializeField] public Monetization Monetization { get; private set; } = Monetization.Free2Play;
[field: SerializeField] public AdBackend AdBackend { get; private set; } = AdBackend.None;
[field: SerializeField] public string SupportUrl { get; private set; } = "mailto:support@honeycombs.games";
...

В рантайме нужный конфиг определяется на основе Scripting Defines
[UsedImplicitly]
public PlatformType GetTypeProd()
{
#if PLATFORM_YANDEX
return PlatformType.Yandex;
#elif PLATFORM_VK_PLAY_DEMO
return PlatformType.VkPlayDemo;
...

и в коде я использую эти настройки через методы в статическом классе Platform:
if (Platform.IsF2P())
{
adManager.ShowRewarded(rewarded =>
{
if (rewarded) Fire();
}, type.ToString());
}
else
{
itemsCount.Coins().ApplyChange(-GetCost());
Fire();
}


4️⃣ Это все основные моменты. Кроме этого, у меня автоматизировано:
1) Автоматическое вписывание версии игры в конфиги аналитики и в настройки Unity.
2) Хак для Text Mesh Pro, чтобы шрифт не попадал в основной билд, а подгружался через Addressables
3) Проверка цепочек квестов на правильность.
4) Определение, подключен ли телефон к компу, чтобы сразу запустить на нем билд.
5) Исключение библиотек из Андроид зависимостей в зависимости от площадки (RuStore/Google Play)
6) В dev режиме доступна панель разработчика с читерскими кнопками (и отключены лидерборды)
7) На Андроиде, если собираю в dev режиме, игра собирается в Mono, а не IL2CPP, т. к. в Mono билд собирается в пять раз быстрее.
8) На Андроиде автоматически вписывается пароль для кейстора (Unity его не сохраняет)
9) Подключаю разные JS SDK (Яндекс/ВКонтакте)

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

#самый_крутяк
  • 🔥 18
Post #130 875
Смотрим метрики после добавления обучения

30 ноября мы выложили в Яндекс Игры обновление, в котором добавили обучение в игру. Обучение состоит из 10 квестов, которые постепенно открывают новые механики и объясняют их диалогами.

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

Но зато, что-то странное происходит с международным рейтингом. Продолжение в комментах...

#бурить_копать #яндекс_игры
  • 👍 7
  • ❤ 2
  • 🥰 1
Post #129 858
Как получить список подключенных (Android) устройств

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

Но мне захотелось ещё больше автоматизации. Я хочу, чтобы если мой телефон подключен к компу, то сборка запускается с флагом BuildOptions.AutoRunPlayer - то есть игра автоматически установится и запустится на телефоне.

Но как определить, подключен телефон или нет? На первой странице гугла не нашлось ответа, и я обратился в ChatGPT с этим вопросом. Результат расстроил.
Unity itself does not provide a built-in API to detect whether an Android device is plugged into a PC, as Unity's scripting is primarily geared toward the game runtime environment rather than system-level interactions.

Однако, ChatGRT ошибается. Достаточно воспользоваться методом DevDeviceList.GetDevices(), чтобы получить список всех доступных девайсов.

Полный код проверки выглядит так:
private static bool IsDeviceConnected()
{
return DevDeviceList.GetDevices()
.Count(device => device is { type: "Android", state: DevDeviceState.Connected }) > 0;
}

#тайные_знания
  • 🔥 15
Post #128 870
У Бурить-Копать! появилась страница в Steam!

Просим добавить игру в желаемое, даже если вы не планируете покупку, это очень сильно поможет нам в продвижении.

https://store.steampowered.com/app/2085020/

#бурить_копать
Steampowered Drill and Dig! on Steam 2D arcade roguelike about digging. Break blocks in search of treasure. Upgrade your drill and skills! Complete quests. Compete with friends and become the best!
  • ❤ 16
  • 👍 5
Post #127 1K
Этой ночью выкатили обновление для игры ВКонтакте. Получается, успели. С нетерпением ждем статистики.
  • 🔥 9
Post #126 1K
Добавляем обучение в Бурить-Копать!

У игры сейчас ужасные показатели R1. На Яндексе 2.4%, в ВК 7%. Наша гипотеза заключается в том, что мы кидаем игрока в песочницу, не даём никакой цели и перегружаем обширным интерфейсом.

Мы добавили в игру обучающую цепочку из 10 заданий. Будем учить игрока собирать топливо, улучшать бур, поджигать динамиты и прокачивать уровень.

По мере прохождения квестов будут открываться соответствующие кнопки/индикаторы в интерфейсе.

На днях будем выпускать обновление в Яндекс Игры и ВКонтакте, очень надеемся на улучшение метрик (ретеншен 1 дня и плейтайм), и мечтаем о воскрешении игры на Яндекса (она с каждым днем получает все меньше и меньше траффика)

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

#бурить_копать #яндекс_игры #игры_вконтакте
  • 🔥 4
  • 👍 3
  • 👀 1
Post #125 880
ВКонтакте устраивает всякие акции и события, чтобы привлечь внимание к играм. В ноябре проходит Календарь наград

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

Мы получим такой же траффик ещё 30 ноября. Очень надеемся успеть сделать обновление с обучением, будет очень интересно сравнить ретеншен 1 дня до и после обновления.

#игры_вконтакте #бурить_копать
Post #124 893
Теперь в моем редакторе атласов можно добавлять новые спрайты

Делаем систему квестов. В ней будут, в том числе, задания типа «Собери 10 ⚙️ запчастей». Именно так, с иконкой в тексте.

Чтобы добавить иконку в TMP Text, нужно создать TMP Sprite Asset, в основе которого лежит Texture2D. По мере добавления квестов, в эту Texture2D будут добавляться новые иконки. Чтобы не добавлять иконку вручную в графическом редакторе, а потом вручную не обводить новый спрайт в Unity, я доработал свой Sprite Animation Importer.

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

Мой Sprite Animation Importer доступен бесплатно всем желающим. Как его добавить, я писал в этом посте. В комментах смотрите видео с демонстрацией работы.

#selfmade
  • ❤ 13
  • 😱 2
  • 👍 1
  • 🔥 1
Post #123 853
Про важность структуры данных

Во время разработки я стараюсь делать так, чтобы сама структура данных уменьшала вероятность возникновения ошибки. Например, в Java я сделаю поле boolean вместо Boolean, чтобы гарантированно не встретить там null.

Или, допустим, мне нужно записать данные нескольких игроков. У игрока два свойства - id и name. Я ни за что не сделаю два массива: int[] ids; string[] names. Я создам класс Player с двумя полями, и массив Player[] players. И никогда не окажусь в ситуации, что ids.Length != names.Length.

При создании таблиц в БД я не забываю про UNIQUE и NOT NULL.

Не забываем ставить 🤡 за такие простые примеры

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

Я написал метод, который проверяет все цепочки квестов, которые лежат в ассетах. Он делает все проверки и бросает исключение, если что-то не так. Я запускаю этот метод автоматически перед билдом, и это гарантирует, что билд не соберется, если в моих квестах будет косяк.

Делай как я.

P. S. В OnValidate я эти проверки не хотел засовывать, он слишком часто вызывается.

#программирование
Telegram SpellSinger - разработчик игр на Unity Как выполнить код перед билдом Addressables? Есть интерфейс IPreprocessBuildWithReport, имплементировав который можно выполнить свой код перед сборкой игры. Однако, сборка Addressables происходит до вызова этого интерфейса. Если нужно как-то поработать…
  • 👍 14
  • 🤡 9
  • ❤ 2
  • 🥱 2
Post #122 863
К шоукейсу готов

Если буду делать ещё какие-нибудь фото/видео с конфы, буду кидать их в комментарии к этому посту.
  • 🔥 22
  • ❤ 1
Post #121 800

Forwarded from RuStore Dev

Показываем красивое: участники зоны шоукейсов на RuStore Mobile Conf: GameDev 😊

На конференции вы сможете протестировать мобильные игры от разработчиков, среди которых есть финалисты проекта «Лаборатория» VK Play и VK Education и конкурса «Начни игру». Познакомьтесь с перспективными играми, узнайте, как они создавались, и лично пообщайтесь с командами проектов!

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

Регистрация на конференцию закроется сегодня в 16:00. Если вы ещё не зарегистрировались, сейчас самое время ✌️
  • 🔥 10
Post #120 700
Участвую в конференции RuStore 2 ноября

Буду шоукейсить с 12:00 до 15:30 и питчить в 20:40. Приходите поддержать и пообщать. Вход бесплатный, но нужна регистрация.
  • 🔥 9
Post #119 863
Отзыв о Hot Reload

Hot Reload компилирует и заменяет содержимое методов на лету без компиляции всего проекта. Даже в Play Mode. Доступен бесплатный 30-дневный триал, после триала будет работать по 2 часа в день.

Ассет действительно умеет подменять внутренности методов, но
- не умеет переименовывать методы
- не умеет менять сигнатуру методов
- не умеет добавлять/переименовывать/удалять поля
- не умеет добавлять/переименовывать/удалять классы

Я поработал с ним день, и 95% времени мне всё равно приходилось перекомпилировать весь код, т. к. я либо добавлял поля, либо рефакторил и выносил код в отдельные методы, либо создавал новые классы.

Окей, Hot Reload мог бы быть полезен в оставшихся 5% случаях. Но в какой-то момент посыпались необъяснимые ошибки, типа NullReferenceException, которые пропали после отключения ассета. На выяснение причин пришлось потратить больше времени, чем сэкономил ассет.

Не рекомендую к использованию.

#отзыв
  • 👍 6
  • ❤ 1
Post #118 720
Убираем GameAnalytics

Мы решили убрать аналитику со всех наших веб площадок, текущих и будущих.

Я был прав, что если используется сторонняя аналитика, то нужно обязательно запрашивать согласие на сбор данных, поддержка Яндекс Игр это подтвердила.

Нам кажется что часть игроков отваливается на этой форме, а бонусов от аналитики мы почти не получаем.

Изначально я планировал использовать аналитику для удаленных конфигов, А/Б-тестов и воронок. И мы действительно несколько раз этим пользовались. Но сейчас нам это не актуально, и мы просто так отпугиваем игроков.

Решили просто убрать стороннюю аналитику. По сути, мы потеряем только в оперативности данных, ведь в Яндексе метрики видны с задержкой в 3-5 дней.

Совсем от аналитики отказываться не планирую, как будет время реализую на своем бэкенде возможность собирать анонимные ивенты без привязки к идентификаторам игроков - такие данные можно собирать без всяких подтверждений. Есть конечно и готовые такие решения, например https://aptabase.com/, но зачем, когда можно изобрести свой велосипед.

На мобилках аналитика останется, но там мы скорее всего будем работать с издателем, и все эти формы и согласия - это их забота.

#аналитика
  • 🔥 8
  • 💩 1
Post #117 622
renderer-sample.unitypackage5.6 KB
Рендерим изображение внутри Unity

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

Полное описание не влезет в пост, поэтому я подготовил unitypackage с примером, а здесь поясню основные моменты:

1) Для создания изображения используется RenderTexture. Внутри префаба находится камера, которая смотрит на содержимое префаба, и записывает то, что видит, в RenderTexture.

2) Размер RenderTexture должен быть равен размеру требуемого изображения. Наверняка можно создать RenderTexture динамически, но мне было проще создать его вручную в ассетах.

3) У меня были проблемы, если я выставлял камере targetTexture = renderTexture в префабе. Поэтому там пусто, и targetTexture задаётся с помощью кода.

4) Изображение можно получить только в конце кадра. Поэтому код работает в корутине, после
yield return new WaitForEndOfFrame();

5) Чтобы префаба не было видно в игре, стоит его вынести в отдельный слой, который не видит основная камера.

#ui #самый_крутяк
  • 👍 9
Post #116 694
Конференция Игровая Индустрия

Привет! Сегодня участвую в шоукейсе на конференции Игровая Индустрия. Ищите меня за столом 101 (самый близкий ко входу).
  • 🔥 12
Post #115 932
Релиз ВКонтакте

Сегодня день рождения у меня и у сына моего любимого художника Нефрита, но отмечаем мы не это, отмечаем мы релиз в играх ВКонтакте!

Было неожиданно непросто добавить все социальные механики в игру, например для кнопки "Поделиться в истории" пришлось генерировать картинку в Unity с динамически проставлямым результатом заезда.

А отправлять результаты в турнирную таблицу ВКонтакте можно только с бэкенда, хорошо, что он у нас уже был. @gs_community, а у вас это уже реализовано?)

Не обошлось и без багов со стороны ВК. На текущий момент я жду решения 4 проблем:
1) В всплывающем окне с рекордами друзей в названии нашей игры вместо восклицательного знака отображается его HTML-код &#33;
2) Это же самое окно не открывается в приложении на Андроид, хотя на ПК и в мобильном браузере открывается.
3) Почему-то стикер в истории не кликабелен в десктопном браузере, но работает как надо в приложении
4) На моем мониторе со стандартным разрешением 1920х1080, периодически появляется и исчезает скроллбар, из-за чего игру потряхивает влево-вправо.

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

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

Играть здесь: https://vk.com/games/app52301788

#игры_вконтакте
  • 🔥 6
  • 🎉 2
  • 👍 1
Post #112 828
Делюсь результатами А/Б теста иконки и обложки

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

По итогу мы оставили новую иконку и обложку, и готовим новый тест.

 P. S. Пришлось всё-таки убрать интерфейс с обложки.
  • 👍 7
  • 🕊 1
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →