Есть поле userData, в которое я обычно записываю json, чтобы можно было хранить вменяемую структуру.

Для этого можно использовать AssetImporter::userData.

Read More  

Используйте вместо new T[0]; статичный массив, который не нужно создавать каждый раз.

Read More  

Например, чтобы сдвинуть объект, который находится в x=10, на 100 юнитов вправо, нужно написать 10+100 и нажать enter.

Еще можно использовать функции L(x, y) и R(x, y), которые выставят выделенные объекты по Lerp и Random соотвественно.

Read More  

Когда-то давно мы делали 3D игру (да, такое тоже было, сейчас от нее остались старые исходники и пара видосов на ютубе).

Тогда в ходу были всякие тулзы  вроде T4M. Но все подобные штуки работают по принципу раскраски или смешивания. Т.е. есть 4 канала маски, а есть 4 текстуры, там где красный - там тайлится первая текстура, где зеленый - вторая и т.д.

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

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

Сегодня используются различные техники при работе с поверхностями начиная от моей любимой «забьем болт» и заканчивая извращениями с шейдерами и дистанцией, но мне все еще нравится способ использовать текстуру плохого качества ;)

Read More  

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

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

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

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

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

Read More  

Для того, чтобы в инспекторе при отрисовке массива отображались нормальные названия элементов, а не Element 0, Element 1, Element N, можно использовать строку первым полем:

struct Item {
   public string key;
   ... 
} 

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

Read More  

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

UnityEngine.Object dir;

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

Read More  

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

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

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

Read More  

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;
} 
Read More  

Иногда в редакторе нужно использовать 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 🙂

Read More  

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


Read More  

Мы знаем, что структуры нужно инициализировать в конструкторе полностью:

struct MyStruct {
     public int field1;
     public int field2;
     ...
     public int fieldN;
     public MyStruct(int field1) {
          this.field1 = field1;
          // тут нужно инициализировать все поля
          this.field2 = default;
          ...
          this.fieldN = default;
     }
} 

Иногда полей много и можно написать гораздо короче:

struct MyStruct {
     public int field1;
     public int field2;
     ...
     public int fieldN;
     public MyStruct(int field1) {
          this = default;
          this.field1 = field1;
     }
} 
Read More