Я уже писал про PackTextures, но эта штука ломается, если невозможно запаковать текстуры, т.к. их размер превышает максимальный размер атласа. Для этого можно использовать GenerateAtlas, т.к. этот метод ничего не делает с текстурами, а только работает с ректами и возвращает true, если все объекты поместятся в атлас. То есть можно сначала вызвать его, а потом использовать PackTextures, либо запаковать самостоятельно, используя SetPixels.

Read More  

Как-то не особо заметно прошло появление этого класса в юнити, но появился он аж в 2019.2.

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

https://docs.unity3d.com/ScriptReference/TypeCache.html

Read More  

В юнити есть замечательная штука, которой мало кто пользуется. На самом деле дает возможность считать отсечение примитивами. На практике я такое часто использую для того, чтобы знать какие объекты нужно просчитывать, а какие - нет. Наверное, это апи можно считать уже устаревшим, т.к. приходят всякие brg, которые умеют в culling, плюс это апи не умеет в burst. Но на самом деле я все равно его использую, т.к. даже на уровне представления оно дает заметный прирост, если самому отключать аниматоры/рендеры и прочие штуки.

https://docs.unity3d.com/Manual/CullingGroupAPI.html

Read More  

Мы храним SystemInfo.deviceUniqueIdentifier, который вовсе не device id, а advertisement id, т.е. раньше он был айдишником девайса, но потом от их использования отказались в пользу различных авторизаций.

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

Когда я разбирал исходники ios, я находил там несколько вариантов этой строки, там был и айди девайса, и мак адрес и всякие другие попытки получить уникальный айди (всего было штук 5, если мне не изменяет память).

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

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

Read More  

Я уже делал пост про FixedUpdate (https://t.me/unsafecsharp/103), но не писал про разницу между fixedDeltaTime и deltaTime.

В методе Update deltaTime будет равен времени, которое прошло с прошлого кадра, при этом fixedDeltaTime будет равен фиксированной величине.

А вот в FixedUpdate fixedDeltaTime останется, а вот deltaTime будет равен fixedDeltaTime. Другими словами, можно использовать deltaTime внутри FixedUpdate.

Read More  

Мы часто используем этот метод для динамического создания атласа, когда, например, мы загружаем аватарки игроков, а какие они будут мы заранее не знаем. Или мы формируем атлас для боя, когда игроки могут выбрать какие-нибудь скины юнитов, а нам все еще нужен 1 draw call ;)

Read More  

Позволяет комбайнить меши, которые находятся на GameObject. Довольно удобно, чтобы не ползать по иерархии и не собирать их там.

Есть способ комбинировать меши и без этого: mesh.CombineMeshes.

Но придется передавать туда уже структуры, в которых описываются матрицы и мешки.

Мы такое часто использовали для 3D, когда мы создавали одну мешку и вместо 1к объектов получали всего один. Есстественно, нужно понимать, что батчить нужно по-материально, т.е. какой-то код с этой логикой нужно будет все же написать.

Read More