Buffer icon Проекты
71 заметка с тегом

разработка

Unity iOS localization

Unity iOS localization scripts

Unity iOS localization scripts

Unity iOS localization scripts

Исходники на Github

Мобильные Unity разработчики меня сейчас должны понять: когда делаешь билд под iOS, то локализацию «из коробки» настроить не получится. Конечно, есть разные ассеты и даже! официальный пакет для локализации. С которым уже можно работать, кстати. Но как обычно, самое интересное в деталях...

Если ваша игра поддерживает несколько языков, к примеру: русский, английский, немецкий, испанский, то для каждого языка неплохо бы сделать локализуемое название игры. Кроме того, если игра/приложение использует камеру или галерею, то нужно показывать диалог запроса прав доступа, тоже локализованный, иначе апрув скорее всего не пройти. Для этого, обычно используется файл InfoPlist.strings и содержимое его выглядит как-то так:
 

"CFBundleDisplayName" = "Локализованное название";
"NSCameraUsageDescription" = "Тут описание зачем приложению доступ к камере";
"NSPhotoLibraryUsageDescription" = "Тут описание зачем доступ к галерее";
"NSPhotoLibraryAddUsageDescription" = "Тут описание зачем доступ к галерее";
"NSUserTrackingUsageDescription" = "Тут описание зачем доступ к IDFA";
 

В общем-то всё это уже можно сделать официальным пакетом локализации, кроме NSUserTrackingUsageDescription по-моему. Но так как я всё равно использую пост-билд скрипт для добавления файлов, фреймворков и установки различных параметров через ProjectCapabilityManager, то использовать ещё один пакет не хотелось бы. Тем более, пакет для локализации сам использует приватные методы пространства имен UnityEditor.iOS.Xcode. Вот тут-то и нашлось решение. С помощью рефлексии вытянуть нужные методы и сделать расширение для PBXProject.

В итоге, получился всего один файл с расширением, который позволяет:

  • очистить неиспользуемые локали
  • добавить используемые языки в приложении, из списка
  • добавить <код_языка>.lproj папки в проект с файлами InfoPlist.strings

В старых проектах я использовал UnityiOSLocalization, он работал, но его «проблема» в большом количестве файлов, которые когда-то были доступны на Bitbucket’е, потом это всё стало приватным — т. е. это то что сейчас получилось вытянуть через рефлексию.

Скорее всего когда допилят официальный пакет, всё это станет не актуальным, ну а пока можно пользоваться.

 Нет комментариев    479   29 дн   ios   unity   разработка   с#
 Нет комментариев    546   2 мес   android   ios   plugin   unity   разработка   с#

Unity и AndroidManifest

Друзья, нас обманывали!

Android Manifest hardwareAccelerated patch

Android Manifest hardwareAccelerated patch

Android Manifest hardwareAccelerated patch
Ещё куча параметров, которые можно установить для Activity

Это такое начало специально, чтобы привлечь внимание :) На самом деле, я просто не знал, что так может быть. Узнал вовремя и хочу поделиться.

Когда вы в своём кастомном андроид манифесте выставляете такую штуку:

<activity android:name="com.xxx.xxx" android:label="@string/app_name" ... android:hardwareAccelerated="true">

И ждёте что будет работать аппаратное ускорение у конкретного активити, то... оно не будет работать. Бум! Т. е. если вы сбилдите apkшку, расковыряете её и посмотрите итоговый манифест, то вместо вашего true будет стоять кое-что другое. Почему так происходит я пока не разобрался, но узнал как исправить.

Оказывается, начиная с 2018 версии в Unity есть такая штука как IPostGenerateGradleAndroidProject. Она вызывается после того как Gradle сделал своё грязное дело и перед непосредственно билдом. Так вот, на этом этапе и можно поменять в манифесте нужные нам параметры. В общем-то, можно добавлять или менять всё что угодно, разрешения, параметры, имена активити и т. д.

Пример на Github

 Нет комментариев    538   2 мес   android   unity   инструменты   разработка

Как использовать Git Submodules в Unity

И тут сразу возникает вопрос: почему не использовать пакеты и UPM? Это удобно, да и весь механизм уже встроен в Unity?

Но как оказалось, не всегда удаётся выделить какую-то часть приложения в отдельный пакет, чтобы у него было минимум зависимостей и он представлял из себя какую-то самостоятельную единицу. Проекты бывают разные, с различной архитектурой и набором дополнительных ассетов и прочего. А выделить какую-то общую часть (ядро) хочется, чтобы использовать её в других проектах... В общем, если по какой-то причине пакеты вам не подходят — попробуйте Git Submodules.

В чём отличие при работе с сабмодулями гита?
Unity использует скрипты и ассеты которые расположены в папке Assets. Если вы попробуйте подключить сабмодуль и указать путь, например Assets/Core, то ничего не получится, потому что папка Assets уже существует. Поэтому надо провернуть такой финт:

  1. Подключаете сабмодуль к проекту (как это сделать, тут описывать не буду, потому что есть разные клиенты SourceTree, Fork, GitKraken, просто консоль)
  2. В качестве директории можно указать Modules/your_module
  3. Переходите в папку Assets
  4. Устанавливаете симлинк (symlink) на новый сабмодуль. Всё! Он у вас в проекте, можно пользоваться.
cd Assets
ln -s ../Modules/Core Core

Выглядеть это будет примерно так:

Unity Git submodules

Unity Git submodules

Unity Git submodules

Теперь если в подключаемых сабмодулях, что-то меняется, надо просто спуллить обновления. В общем, кто привык работать с Git, то всё достаточно привычно и понятно.

 Нет комментариев    1002   2 мес   git   unity   инструменты   разработка

MoDI

MoDI. Lightweight IoC container for Unity.

MoDI. Lightweight IoC container for Unity.

MoDI. Lightweight IoC container for Unity.

MoDI — простой контейнер для внедрения зависимостей в Unity.

Когда я хочу в чём-то разобраться, я почти сразу перехожу к практической части. Если со старта не получается, тогда начинаю читать мануалы :) После этого, снова повторяю шаг №1 и так по кругу. Иногда это надоедает и я или ищу другие пути решения, или говорю себе, что это «не моё», мне это не надо — сдаюсь короче.

Решил я однажды разобраться как работать с Zenject и Ninject в Unity. Сделал несколько тестовых проектов — вроде работает. Начал копать дальше, понял принцип и решил, что хочу своё такое же, но попроще :) И чтобы было достаточно для всех моих разработческих потребностей. Так появился MoDI.

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

Это можно сказать и про ECS, да Leopotam? :)

MoDI можно подключить к проекту с помощью пакетного менеджера, через него же можно импортировать сцену с примерами. Ну или просто скачать архив и добавить в проект.

Простейший пример выглядит так:

using MoDI;
using UnityEngine;

public class QuickStart : MonoBehaviour {

    public void Start() {
        DI.Get().Bind<Hello>().WithArguments("Hi, I'm MoDI!");
        Hello hello = DI.Get().Resolve<Hello>();
    }
    
}

public class Hello {

    public Hello(string data) {
        Debug.Log(data);
    }

}

После запуска данного скрипта в консоли появится сообщение: «Hi, I’m MoDI!».

В документации можно найти ещё примеры и описание API.

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

 1 комментарий    2259   7 мес   unity   ассеты   инструменты   разработка   с#

200 звёзд на Github

Achievement unlocked!

Моё новое скромное достижение. Скрипт с data-driven прокруткой для Unity, получил 200 звёзд на Github. Спасибо S1ROZHA :)

Infinite scroll unity 200 stars

Infinite scroll unity 200 stars

Infinite scroll unity 200 stars

Мне как-то писали, что используют его в MTG Arena и ещё какой-то популярной игре. Приятно что этим пользуюсь не только я.

 Нет комментариев    2345   11 мес   git   ассеты   проекты   разработка

Командный бой на Unity (пример)

Так и не придумал как будет правильней назвать этот пример :)

Unity team fight example

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

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

Из положительных моментов: почти не выделяется память, только на корутины анимации (но это можно убрать) и все отрисовывается за 2-4 DC.

Исходники на Github

 Нет комментариев    1393   11 мес   unity   игры   разработка   с#

Создание плагинов для Unity

Плагины для Unity

Плагины для Unity

Плагины для Unity

Пишу статью про создание плагинов для Unity под iOS и Android. Нужны комменты и советы.

За несколько лет, я сделал большое количество различных плагинов. Многие они не в паблике и опенсорс, но это не надолго (надеюсь :).

Есть куча ситуаций когда одной Unity недостаточно и нужно использовать возможности платформы. Банально, но до сих пор, в Unity нет работы с галерей и камерой из коробки :) Смешно? Не очень. В Xamarin есть, а в Unity нет.

Для многих менее опытных разработчиков, создание плагина для Unity под мобильную платформу кажется чем-то сложным, но на деле, это не так сложно и страшно. По крайней мере, организовать простое взаимодействие — достаточно просто. В статье, будет шаблон для Android (на Java) и iOS (на Obj-C) для создания плагинов и их связи с Unity приложением.

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

 1 комментарий    1210   1 год   android   apple   camera   ios   plugin   unity   разработка   с#

Unity EventBus на интерфейсах

public class SaveLoadManager : Monobehaviour, IQiuckSaveHandler
{
    private void OnEnable()
    {
        EventBus.Subscribe(this);
    }

    private void OnDisable()
    {
        EventBus.Unsubscribe(this);
    }

    private void HandleQuickSave()
    {
        // код сохранения
        ...
    }
}

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

 Нет комментариев    1225   1 год   unity   разработка   с#   ссылки

Unity & iOS capabilities

iOS capabilities list

iOS capabilities list

iOS capabilities list

Как оказалось, даже для последних версий Unity, есть проблема программно выставить нужные параметры в Xcode проекте :( А это необходимость, иначе никакой CI\CD не работает и придётся билдить iOS версию вручную, что конечно не очень правильно.

Для этих целей в Unity есть специальный PostProcessBuildAttribute и PBXProject. После билда в Xcode проект, можно настраивать уже другие параметры, не доступные внутри Unity. Но, даже следуя мануалам, как-то оно не всё работает...

Так, например, чтобы добавить функцию Sign in with Apple, нужно воспользоваться ProjectCapabilityManager. В коде это выглядит примерно так:

...
string projectPath = string.Format ("{0}/Unity-iPhone.xcodeproj/project.pbxproj", path);
PBXProject project = new PBXProject ();
string file = File.ReadAllText (projectPath);
project.ReadFromString (file);
string target = project.GetUnityMainTargetGuid ();
string entFile = "game.entitlements";
ProjectCapabilityManager manager = new ProjectCapabilityManager (projectPath, entFile, "Unity-iPhone", target);
manager.AddSignInWithApple ();
// other capabilities
manager.WriteToFile ();

Но таким образом файл X.entitlements не добавляется в проект, создаётся, но не добавляется. И через project.AddFile() — тоже. Спасает как всегда stackoverflow :) Оказывается, помимо project.AddFile() надо добавить ещё специальный property, чтобы всё закрутилось:

...
project.AddFile (entFile, entFile);
project.AddBuildProperty (target, "CODE_SIGN_ENTITLEMENTS", entFile);
File.WriteAllText (projectPath, project.WriteToString ());

Почему это не написано в мануале Unity — непонятно.

 Нет комментариев    487   2020   ios   unity   разработка   с#
Ранее Ctrl + ↓