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

Читать далее  

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

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

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

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

Читать далее  

Давайте сначала разберемся, что такое Лерп. Это линейная функция, которая задается двумя точками B и C (см изображение), третье значение t — это как значение между 0 и 1, где 0 — это B, а 1 — это C.

Таким образом получается, что перемещение по линии - это и есть lerp или интерполяция. А вот LerpUnclamped - это экстраполяция, т.е. когда мы не обрезаем значение t до 0..1.

 б + (с - б) * зажим01(т);

Т.е. по сути мы сначала меняем набор координат на ноль (c - b), а потом умножаем получившийся вектор на t, а после постепенно набираемый вектор назад.

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

Читать далее  

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

А теперь самое инетерсное, начал разбираться и оказалось, что наш картоделатель посадил по 5к юнитов в домики "за картой", чтобы потом оттуда пускать их по триггеру. А рендер работает таким образом, что ему нужно знать верхнее ограничение по отрисовке количества юнитов. Для нормальной игры это вычислялось по формуле: "берем сумму всех юнитов во всех домиках на карте и умножаем на количество игроков (т.к. в теории каждый игрок может применить какой-нибудь скилл, который сдублирует юнитов, например)". Но если вдруг мы что-то не учли - мы просто не рисуем юнитов и все, что в принципе ок, т.к. когда у тебя 1к юнитов на экране - ты уже не понимаешь где кто, а когда 4к - так и подавно.

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

Так вот мы жили с такой игровой картой уже месяца 3 и только сейчас заметили проблему на девайсе с памятью, хотя у нас вместо того, чтобы рисовать и обрабатывать 4к юнитов максимум (+рендер на 20к), мы вдруг начали обрабатывать 220к и никто этого не заметил... И, наверное, если бы не этот девайс - так бы и пошли в релиз 🙂

А вы все "преждевременная оптимизация, преждевременная оптимизация..." 😂

Читать далее  

Если вы не используете параметр <span>out</span>, по которому возвращается значение, то можете писать просто _:

Method(out int notUsed);
Method(out _);
Читать далее  

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

На примере легко получить такую ​​проблему в системе партий с тысячами частиц. Может показаться, что производительность падает из-за количества частиц, но на самом деле проблема на 99% в перерисовке. Кстати, для этого в системе рендеринга партийной системы есть параметр, который ограничивает максимальный размер частиц относительно размера экрана, т.к. чем больше площадь - тем хуже. Поэтому 100 больших частиц в камере хуже, чем 10к, но далеко.

Читать далее  

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

Я часто встречаю вот такой код:

 а += б/2ф;

И мне все время такое хочется, напиши такой код:

 а += б * 0,5f;

Также можно заменить любые другие константы по тому же принципу. Но что делать, если у нас разделение не на константу, а на x? Да все просто, делаем y = 1f / x и используем уже y.

Читать далее  

Мы часто используем редактор полей вида:

 Каталог UnityEngine.Object;

для того, чтобы в инспекторе перетащить к фиксатору. Очень удобно не писать константы в коде.

Читать далее  

Их нет, да, но как тогда работают дженерики, которые мы делаем на C#? Там то они есть;) а мы используем il2cpp почти всегда для продакшена. В итоге под каждый тип, который мы вызываем, будет создан метод. Это стоит учитывать, когда вы создаете общий метод и выполняете миллион разных вариантов вызовов, ожидайте, что код будет использован в нескольких миллионах копипастных методов;)

Читать далее  

Допустим, что вам нужно найти середину связного списка, как это быстрее всего сделать? Завести 2 указателя, один будет шагать через один элемент, а второй - по каждому элементу. Таким образом когда первый указатель доберется до конца такого списка - второй будет указывать на середину. Так вот первый указатель называют "быстрым".

Недавно встретил такую задачку и хотел бы с вами поделиться:

На вход нашему методу передается некий граф, который содержит ноды вида

Node {
  int value;
  Node next;
}

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

Например:

1 -> 2 -> 3 -> 4 -> 2

Тут нода со значением 2 начинает цикл.

Если же ноды нет, то метод должен вернуть null.

Решение этой задачи довольно простое, если бы не одно условие: нужно найти решение без использования дополнительной памяти.

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

p.s: задача была задана на собесе в компанию Apple.

Читать далее  

Довольно простой вопрос, который решается банальной проверкой (v2.sqrMagnitude <= radius * radius). Мы такой вопрос часто задаем на собесах, но не только для того, чтобы выяснить считает ли человек через квадрат радиуса, а скорее для того, чтобы задать второй вопрос: "а в эллипс?". И вот на этом вопросе люди начинают сами себя закапывать. Кто-то придумывает несуществующие правила и теоремы, кто-то говорит, что мол "да я это не помню, там высшая математика, кому это вообще надо", ну а кто-то предлагает решение.

А самое интересное, что решение довольно простое, которое не требует никаких знаний и формул:

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

Читать далее  

Он сравнивает не точное значение, а приблизительное, с учетом погрешностей:

 вар v = новый Vector3 (0f, 0f, 0f);
вар v2 = Vector3.one - Vector3.one;

v == v2
Читать далее