TGViewer
Channel Public Channel
Unity: Всё, что вы не знали о разработке

Unity: Всё, что вы не знали о разработке

@unsafecsharp

Авторский канал о разработке в Unity от Alex Silaev (CTO в Zillion Whales). Mushroom Wars 2 моих рук дело.
Рассказываю об интересный кейсах, делюсь лайфхаками, решениями.
Subscribers
1.73K
Photos
40
Videos
0
Links
101

Showing posts older than #102 · Back to latest

Older Posts 20 shown
Post #101
Unity: Всё, что вы не знали о разработке pinned «https://unsafecsharp.timepad.ru/event/2464311/ В следующую субботу проведу лекцию на тему мультиплеера в играх. Обсудим какой вариант лучше выбрать, какие варианты синхронизации существуют. Регайтесь 🙂 #event»
Post #100 1.22K
Кто такой Лисков?

Обычно такой вопрос был у нас на собесах N лет назад. И правильный ответ на него должен быть один: он - Барбара.

#interview
  • 😁 27
  • 🤡 3
  • 🐳 1
Post #99 1.28K
https://unsafecsharp.timepad.ru/event/2464311/

В следующую субботу проведу лекцию на тему мультиплеера в играх. Обсудим какой вариант лучше выбрать, какие варианты синхронизации существуют.
Регайтесь 🙂

#event
unsafecsharp.timepad.ru Мультиплеер в играх / События на TimePad.ru О вариантах синхронизации в мп играх различных жанров
  • 🔥 32
Post #98 1.19K
Напоминаю, что уже почти через час я проведу лекцию на тему архетипов и компонентов в ецс. Кто еще не зарегался - регайтесь. Надеюсь, что будет интересно.

https://t.me/unsafecsharp/92

#event
Telegram Unity: Всё, что вы не знали о разработке https://unsafecsharp.timepad.ru/event/2460193/ Итак, в эту субботу пройдет небольшая лекция на тему ECS + ответы на вопросы по теме. #event
  • 🔥 16
Post #97 1.1K
Немного про оценку сложности алгоритмов.

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

int Method(int n) {
var sum = 0;
for (int i = 0; i < n; ++i) {
sum += i;
}
return sum;
}


Т.е. мы передаем в метод некое число n, которое обозначает количество итераций цикла внутри метода. Верхняя сложность такого алгоритма будет O(n). При этом если мы добавим в конец метода еще несколько строк:

for (int i = 0; i < 10; ++i) {
sum += i;
}

то казалось бы, что сложность должна увеличиться на 10 (O(n + 10), но в О-нотации это будет константное время, а значит мы не будем учитывать это в сложности, т.е. сложность все еще останется O(n).

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

Вот для сравнения методы со сложностью O(n) и O(1).

Метод O(n):

int Method(int n) {
var sum = 0;
for (int i = 0; i < n; ++i) {
sum += i;
}
return sum;
}


Метод O(1):

int Method() {
var sum = 0;
for (int i = 0; i < 100_000; ++i) {
sum += i;
}
return sum;
}


Как видно из примера, любой вызов первого метода с n < 100_000 будет отрабатывать быстрее, чем второй метод с константным временем выполнения. Так что когда вам говорят, что какая-то коллекция работает за константное время на добавление элементов, например, то это совсем не означает что она делает это максимально эффективно.

#algorithms #notations #basics
  • 🔥 14
  • 👍 7
Post #96 1.06K
🥕Синхронизация ME.BECS работает хорошо) 1.5к кубиков и примерно 300 байт передачи по сети.
Главное отличие от ME.ECS будет в том, что будет поддержка нескольких типов синхронизаций и полноценная сингл поддержка без сети вообще :)
  • ❤ 25
  • 🤯 2
Post #94 1.24K
Как работают корутины

Чтобы понять как они работают, нужно понять как работает Enumerator. Если коротко, то это некий объект, у которого есть метод MoveNext(), если его вызвать, то произойдет переключение на следующий шаг:

// step 1
yield return null;
// step 2


А теперь каким образом юнити собственно это делает. Раз у нас есть объект, мы можем добавить его в какой-нибудь список.

IEnumerator MyMethod() {
// step 1
yield return null;
// step 2
}

list.Add(MyMethod());


А теперь в update мы просто переключаем шаги:

for (int i = 0; i < list.Count; ++i) {
if (item.MoveNext() == false) {
item.Current // тут мы можем проверить возвращаемое значение, например, если там внутренняя корутина, то ее тоже хорошо бы выполнить 🙂
list.RemoveAt(i);
--i;
}
}

Таким образом, мы будем выполнять шаги, пока есть чего выполнять.
Корутины в юнити работают примерно таким образом. Еще я бы добавил, что при вызове StartCoroutine сразу выполняется первый шаг, т.е. вызывается MoveNext(), если он возрващает true, то значит дальше что-то есть и нужно добавлять корутину в список выполнения.

Т.е. нужно понять главное: корутины - это не какая-то особенная штуковина, которая работает только в юнити, это стандартный синтаксис и коллекции C#.
  • 👍 32
Post #93 1.14K
Как сделать миникарту

На самом деле вариантов всего три:
1. Вы делаете дополнительную ортографическую камеру, которая снимает сверху весь ваш мир (или нужный кусок), которая может исключать определенные слои или, напротив, включать определенные слои, которые не видит основная камера.
2. Вы для каждого объекта считаете позицию в мире и проецируете ее на UI, т.е. если позиция объекта в мире находится в точке 10;20 и размер мира 100x100, то на миникарте эта позиция будет 10/100;20/100 в процентах, а значит умножив полученные проценты на размер миникарты - получим точку в UI миникарты.
3. Гибридный вариант. Когда мы можем снимать некоторые объекты "как есть", а потом накладывать поверх уже вариант 2 для pixel-perfect варианта.

Еще я бы сюда добавил такой интересный момент: для 1-го варианта можно использовать лоды, чтобы сократить количество треугольников + сократить количество draw call.
Я предпочитаю использовать только второй вариант + подкладывать (или вообще не использовать) фон.

#minimap #rendering
  • 👍 29
  • ❤ 2
Post #92 1.15K
Post #91 1.15K
  • ❤ 8
Post #90 1.16K
Post #89 1.35K
Post #88 1.1K
Давайте сыграем в небольшую игру.
Я сделал следующий пост, но я немного "спрятал", попробуйте его найти (ессно я выложу пост позже, но если тема зайдет - могу делать более интересные штуки).
От меня - кто первым выложит текст поста в комменты получит от меня 10 евро (Перевод по IBAN).

https://postimg.cc/Mnc2WqhW

#thegame
  • 🔥 3
  • 🤔 2
  • 🤡 2
Post #87 1.21K
Post #86 1.11K
Размер указателя зависит от платформы, на которой выполняется код. На 32-битных платформах размер указателя равен 4 байта, а на 64-битных - 8 байт.

#basics #pointers
  • 👍 15
  • 🥱 11
Post #85 1.18K
Избавляемся от if в шейдерах.
Мы знаем, что if в шейдере - плохо. На самом деле бывает плохо, а бывает и нормально. Тут зависит от условия и что мы в нем делаем. Но я предпочитаю не полагаться на компилятор, а просто не использовать if-конструкции.

https://telegra.ph/Izbavlyaemsya-ot-if-v-shejderah-06-01

#shaders #performance
Telegraph Избавляемся от if в шейдерах Мы знаем, что if в шейдере - плохо. На самом деле бывает плохо, а бывает и нормально. Тут зависит от условия и что мы в нем делаем. Но я предпочитаю не полагаться на компилятор, а просто не использовать if-конструкции. Давайте разберем простой пример: half4…
  • 🔥 12
  • 🥱 4
  • 🤔 1
Post #83 1.13K
Интересное.

public T A<T>() where T : struct {
var t = new T();
...
return t;
}

Вот такой код мы обычно воспринимаем как "сделать default значение и потом мы его вернем". Все бы ничего, но это не совсем так. Вот как будет выглядеть этот код:

public T A<T>() where T : struct {
var t = System.Activator.CreateInstance<T>();
...
return t;
}


Исправить это довольно просто:

public T A<T>() where T : struct {
T t = default;
...
return t;
}


#performance #lifehack #structs
  • 👍 26
  • ❤ 1
Post #82 1.11K
Когда проект все еще работает, но в коде встречаешь вот такое :)

#meme
  • 😁 20
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 →