Vector3.Distance или (a - b).sqrMagnitude?Я часто встречаю в различных проектах первый вариант при поиске ближайшей цели, например. Уж не знаю почему так получается, но, наверное, люди не особо вникают в то как это работает.
sqrMagnitude внутри: x*x + y*y + z*zVector3.Distance внутри: sqrt(x*x + y*y + z*z)В
sqrMagnitude по теореме Пифагора мы вычисляем расстояние между точками, тут все просто.Но когда мы можем использовать
sqrMagnitude? Самое банальное: проверка расстояния, когда каждая точка вычисляет расстояние одинаково. Получается, что корень считать нам нет никакой нужды, если нам нужно найти ближайший объект или, например, определить находится ли юнит в радиусе для выстрела.#math #performance #basics
👍30🥱7⚡2
Иногда в редакторе нужно использовать
Для этого можно использовать простой хак:
Еще нужно не забыть убить этот
#editor #lifehack #serializedproperty #serializedreference
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
👍20🔥2
Небольшая заметка:
Довольно часто мы пишем в коде подобные штуки:
Фактически мы умножаем Vector direction на float и на какой-нибудь мультипликатор, например, 2. На самом деле лучше писать вот так:
Т.к. в таком случае операций умножения для вектора будет одна вместо двух.
#performance #math #basics
Довольно часто мы пишем в коде подобные штуки:
direction * deltaTime * 2fФактически мы умножаем Vector direction на float и на какой-нибудь мультипликатор, например, 2. На самом деле лучше писать вот так:
direction * (deltaTime * 2f)Т.к. в таком случае операций умножения для вектора будет одна вместо двух.
#performance #math #basics
👍44🔥8🤔1
Используйте
Поясню. UnsafeList - это прямой доступ к аллоцированной памяти, а NativeList содержит в себе указатель на UnsafeList, таким образом, чтобы дойти до данных списка нужно обратиться к указателю.
Из минусов - отсутствие safety handler.
Важно: UnsafeList содержит данные о количестве элементов, т.е. относиться к этой структуре нужно как к любому ValueType (оно будет копироваться).
В принципе это касается всех коллекций.
#performance #unsafe #collections
UnsafeList вместо NativeList где это возможно.Поясню. UnsafeList - это прямой доступ к аллоцированной памяти, а NativeList содержит в себе указатель на UnsafeList, таким образом, чтобы дойти до данных списка нужно обратиться к указателю.
Из минусов - отсутствие safety handler.
Важно: UnsafeList содержит данные о количестве элементов, т.е. относиться к этой структуре нужно как к любому ValueType (оно будет копироваться).
В принципе это касается всех коллекций.
#performance #unsafe #collections
👍9❤1
Интересное.
Вот такой код мы обычно воспринимаем как "сделать default значение и потом мы его вернем". Все бы ничего, но это не совсем так. Вот как будет выглядеть этот код:
Исправить это довольно просто:
#performance #lifehack #structs
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
Избавляемся от if в шейдерах.
Мы знаем, что if в шейдере - плохо. На самом деле бывает плохо, а бывает и нормально. Тут зависит от условия и что мы в нем делаем. Но я предпочитаю не полагаться на компилятор, а просто не использовать if-конструкции.
https://telegra.ph/Izbavlyaemsya-ot-if-v-shejderah-06-01
#shaders #performance
Мы знаем, что if в шейдере - плохо. На самом деле бывает плохо, а бывает и нормально. Тут зависит от условия и что мы в нем делаем. Но я предпочитаю не полагаться на компилятор, а просто не использовать if-конструкции.
https://telegra.ph/Izbavlyaemsya-ot-if-v-shejderah-06-01
#shaders #performance
Telegraph
Избавляемся от if в шейдерах
Мы знаем, что if в шейдере - плохо. На самом деле бывает плохо, а бывает и нормально. Тут зависит от условия и что мы в нем делаем. Но я предпочитаю не полагаться на компилятор, а просто не использовать if-конструкции. Давайте разберем простой пример: half4…
🔥12🥱4🤔1
Как мы рисуем стрелку приказов.
https://telegra.ph/Kak-my-risuem-strelku-prikazov-06-03
#arrows #graphics #mesh
https://telegra.ph/Kak-my-risuem-strelku-prikazov-06-03
#arrows #graphics #mesh
Telegraph
Как мы рисуем стрелку приказов
Как мы рисуем стрелку приказов. У нас прошло несколько этапов рисования стрелки: в Mushroom Wars 1 это был большой спрайт, в Mushroom Wars 2 мы основательно подошли к этому вопросу и начали генерить меш для стрелки сами, а вот в новых проектах мы не используем…
🔥29👍8🤔2
Давайте сыграем в небольшую игру.
Я сделал следующий пост, но я немного "спрятал", попробуйте его найти (ессно я выложу пост позже, но если тема зайдет - могу делать более интересные штуки).
От меня - кто первым выложит текст поста в комменты получит от меня 10 евро (Перевод по IBAN).
https://postimg.cc/Mnc2WqhW
#thegame
Я сделал следующий пост, но я немного "спрятал", попробуйте его найти (ессно я выложу пост позже, но если тема зайдет - могу делать более интересные штуки).
От меня - кто первым выложит текст поста в комменты получит от меня 10 евро (Перевод по IBAN).
https://postimg.cc/Mnc2WqhW
#thegame
🔥3🤔2🤡2
Постарался просто описать Cross и Dot
https://telegra.ph/Cross-i-Dot-prostymi-slovami-06-03
#basics #math
https://telegra.ph/Cross-i-Dot-prostymi-slovami-06-03
#basics #math
Telegraph
Cross и Dot простыми словами
Cross Product (векторное произведение) - по сути это способ нахождения нормали. Если у нас есть 2 вектора, то эти два вектора так или иначе образуют плоскость. Так вот Cross дает нам нормаль этой плоскости. Направление этой нормали (она же может смотреть…
👍22
Друзья! Хочу понять какая собралась аудитория. Мне это поможет с постами, плюс я хочу провести первую лекцию на какую-нибудь тему (пишите темы комменты).
Anonymous Poll
13%
Изучаю юнити 0-1 год
30%
1-3 года
26%
3-5 лет
23%
5+
8%
Я ваще крутой перец и сам всё знаю
❤8
https://unsafecsharp.timepad.ru/event/2460193/
Итак, в эту субботу пройдет небольшая лекция на тему ECS + ответы на вопросы по теме.
#event
Итак, в эту субботу пройдет небольшая лекция на тему ECS + ответы на вопросы по теме.
#event
unsafecsharp.timepad.ru
ECS: Архетипы и компоненты / События на TimePad.ru
Рассказываю как устроены архетипы и каким образом хранятся компоненты в ECS, отвечаю на вопросы по теме
👍19🔥4❤2
Как сделать миникарту
На самом деле вариантов всего три:
1. Вы делаете дополнительную ортографическую камеру, которая снимает сверху весь ваш мир (или нужный кусок), которая может исключать определенные слои или, напротив, включать определенные слои, которые не видит основная камера.
2. Вы для каждого объекта считаете позицию в мире и проецируете ее на UI, т.е. если позиция объекта в мире находится в точке 10;20 и размер мира 100x100, то на миникарте эта позиция будет 10/100;20/100 в процентах, а значит умножив полученные проценты на размер миникарты - получим точку в UI миникарты.
3. Гибридный вариант. Когда мы можем снимать некоторые объекты "как есть", а потом накладывать поверх уже вариант 2 для pixel-perfect варианта.
Еще я бы сюда добавил такой интересный момент: для 1-го варианта можно использовать лоды, чтобы сократить количество треугольников + сократить количество draw call.
Я предпочитаю использовать только второй вариант + подкладывать (или вообще не использовать) фон.
#minimap #rendering
На самом деле вариантов всего три:
1. Вы делаете дополнительную ортографическую камеру, которая снимает сверху весь ваш мир (или нужный кусок), которая может исключать определенные слои или, напротив, включать определенные слои, которые не видит основная камера.
2. Вы для каждого объекта считаете позицию в мире и проецируете ее на UI, т.е. если позиция объекта в мире находится в точке 10;20 и размер мира 100x100, то на миникарте эта позиция будет 10/100;20/100 в процентах, а значит умножив полученные проценты на размер миникарты - получим точку в UI миникарты.
3. Гибридный вариант. Когда мы можем снимать некоторые объекты "как есть", а потом накладывать поверх уже вариант 2 для pixel-perfect варианта.
Еще я бы сюда добавил такой интересный момент: для 1-го варианта можно использовать лоды, чтобы сократить количество треугольников + сократить количество draw call.
Я предпочитаю использовать только второй вариант + подкладывать (или вообще не использовать) фон.
#minimap #rendering
👍29❤2
Как работают корутины
Чтобы понять как они работают, нужно понять как работает
А теперь каким образом юнити собственно это делает. Раз у нас есть объект, мы можем добавить его в какой-нибудь список.
А теперь в update мы просто переключаем шаги:
Таким образом, мы будем выполнять шаги, пока есть чего выполнять.
Корутины в юнити работают примерно таким образом. Еще я бы добавил, что при вызове
Т.е. нужно понять главное: корутины - это не какая-то особенная штуковина, которая работает только в юнити, это стандартный синтаксис и коллекции C#.
Чтобы понять как они работают, нужно понять как работает
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
Unity: Всё, что вы не знали о разработке pinned «https://unsafecsharp.timepad.ru/event/2460193/ Итак, в эту субботу пройдет небольшая лекция на тему ECS + ответы на вопросы по теме. #event»
