Unity: Всё, что вы не знали о разработке – Telegram
Unity: Всё, что вы не знали о разработке
1.74K subscribers
40 photos
101 links
Авторский канал о разработке в Unity от Alex Silaev (CTO в Zillion Whales). Mushroom Wars 2 моих рук дело.
Рассказываю об интересный кейсах, делюсь лайфхаками, решениями.
Download Telegram
🥕Задачка
У вас есть строка вида «aabbbccde»
Вам нужно написать алгоритм, который уберет все дубликаты символов, которые стоят вместе, то есть останется только «abcde». Для строки «aabbccaabb» ответ будет «abcab».
Нужен алгоритм, использовать всякие regex нельзя;)
🥱10👍3🤔2
🥕ME.BECS
Примерно вот так выглядит граф систем в ME.BECS :)
👍9🔥7
Давайте напишем счетчик, значение которого мы хотим увеличивать из разных потоков, а после того как все потоки закончат работу, мы выводим это число.


public class Counter {
public int value;
public void Increment() => Interlocked.Increment(ref this.value);
}


Вот вроде бы и все, но на самом деле - можно быстрее. Каким образом?


public class Counter {
public int[] values;
public int Count {
get {
var count = 0;
for (int i = 0; i < this.values.Length; ++i) count += this.values[i];
return count;
}
}
public void Increment(int threadIndex) => ++this.values[threadIndex];
}

Т.е. мы должны знать количество потоков и порядковый номер потока, в котором работаем (В Unity Jobs есть JobsUtility.ThreadIndex и JobsUtility.ThreadIndexCount).
Т.е. мы создаем Counter с массивом по количеству потоков и при каждой операции Increment мы передаем номер текущего потока. Тогда этот счетчик будет работать без оверхеда на добавление совсем. А когда операции закончились - мы суммируем все счетчики и возрващаем значение.

#multithreading #threading #collections #lockfree
👍17🤯5
Используйте указание на конкретный тип в enum, если вы используете меньше, чем int:

enum MyEnum : byte {
Value1,
Value2,
Value3,
Value4,
}


Таким образом:

struct Test {
public MyEnum e1;
public MyEnum e2;
public MyEnum e3;
public MyEnum e4;
}


Будет запаковано как 4 байта. Но не забывайте, что любая математика с enum приводит к int 🙂

#enum #code #structlayout
👍19🔥4
🥕Задачка
Предыдущая задачка была совсем простая, поэтому вот вам посложнее, но снова про строки;)

У вас есть строка вида «aabbbccde»
Вам нужно написать алгоритм, который переставит символы так, чтобы не осталось символов, идущих подряд. Если это невозможно, то вернуть null.
«aabbbccde» = «ababcbcde»
«aaccbbcccc» = null
«aabbaac» = «ababaca»
«aaabbbb» = «bababab»

Дополнительно:
Возможно ли эту задачу без аллокаций, если исходная строка приходит в виде массива char?
🤔4
🥕Как определить пересекаются ли OBB и OBB?

OBB - это Oriented Bounding Box, это такой Rect с поворотом, но в 3D 🙂

Попробуйте ответить на этот вопрос до того, как посмотрите мое решение. Напишите в комменты свой вариант решения (просто описание алгоритма) хотя бы для 2D. Интересно было бы сравнить.

Мой вариант решения тут:
https://telegra.ph/Kak-poschitat-peresechenie-OBB-i-OBB-05-30
🔥8
Давайте немного про сеть поговорим.

Какие протоколы мы используем?

TCP (Transmission Control Protocol) и UDP (User Datagram Protocol) - это два наиболее распространенных протокола передачи данных. Основное отличие между ними заключается в том, что TCP является протоколом, обеспечивающим надежную передачу данных, а UDP - протоколом без установления соединения и без гарантии доставки данных.

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

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

RUDP (Reliable User Datagram Protocol) - это протокол, который сочетает в себе преимущества TCP и UDP. Он обеспечивает надежную передачу данных, как TCP, но без установления соединения, как UDP. RUDP используется для передачи данных с гарантией доставки, но не гарантирует порядок пакетов.

В случае с TCP при получении пакетов 1, 3, 4, 5, TCP отдаст только пакет 1, а остальные пакеты придержит до тех пор, пока пакет 2 не будет доставлен. Таким образом можно замечать некую «тормознутость» при использовании TCP, когда пакетов нет-нет, а потом хоп, и вдруг сразу и много. С RUDP/UDP такого не происходит.

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

#network #theory
😁20👍12🥱2
У SerializedProperty появился boxedValue. Не во всех случаях он работает, но во всяком случае для большого числа кейсов можно теперь читать и писать значение нормально 🙂

#editor #serializedproperty
👍9🔥3🥰1
Занимательная геометрия.

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

#geometry #math #lifehack
👍21🤔8🤯41😁1
Vector3.Distance или (a - b).sqrMagnitude?

Я часто встречаю в различных проектах первый вариант при поиске ближайшей цели, например. Уж не знаю почему так получается, но, наверное, люди не особо вникают в то как это работает.
sqrMagnitude внутри: x*x + y*y + z*z
Vector3.Distance внутри: sqrt(x*x + y*y + z*z)

В sqrMagnitude по теореме Пифагора мы вычисляем расстояние между точками, тут все просто.
Но когда мы можем использовать sqrMagnitude? Самое банальное: проверка расстояния, когда каждая точка вычисляет расстояние одинаково. Получается, что корень считать нам нет никакой нужды, если нам нужно найти ближайший объект или, например, определить находится ли юнит в радиусе для выстрела.

#math #performance #basics
👍30🥱72
Иногда в редакторе нужно использовать SerializedProperty у объекта, до которого просто никак не дойти. Допустим, я хочу вывести поля класса, а класс этот находится не в ScriptableObject и не в компоненте.
Для этого можно использовать простой хак:

public class Temp : ScriptableObject {
[SerializedReference]
public object data;
}

var temp = Temp.CreateInstance<Temp>();
temp.data = yourInstance;
var so = new SerializedObject(temp);
var prop = so.FindProperty("data");


Еще нужно не забыть убить этот Temp 🙂

#editor #lifehack #serializedproperty #serializedreference
👍19🔥2
Небольшая заметка:

Довольно часто мы пишем в коде подобные штуки:
direction * deltaTime * 2f

Фактически мы умножаем Vector direction на float и на какой-нибудь мультипликатор, например, 2. На самом деле лучше писать вот так:
direction * (deltaTime * 2f)

Т.к. в таком случае операций умножения для вектора будет одна вместо двух.

#performance #math #basics
👍44🔥8🤔1
Используйте UnsafeList вместо NativeList где это возможно.
Поясню. UnsafeList - это прямой доступ к аллоцированной памяти, а NativeList содержит в себе указатель на UnsafeList, таким образом, чтобы дойти до данных списка нужно обратиться к указателю.
Из минусов - отсутствие safety handler.
Важно: UnsafeList содержит данные о количестве элементов, т.е. относиться к этой структуре нужно как к любому ValueType (оно будет копироваться).

В принципе это касается всех коллекций.

#performance #unsafe #collections
👍91
Когда проект все еще работает, но в коде встречаешь вот такое :)

#meme
😁20
Интересное.

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
👍261
Избавляемся от if в шейдерах.
Мы знаем, что if в шейдере - плохо. На самом деле бывает плохо, а бывает и нормально. Тут зависит от условия и что мы в нем делаем. Но я предпочитаю не полагаться на компилятор, а просто не использовать if-конструкции.

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

#shaders #performance
🔥12🥱4🤔1