Skip to content
Alex Feer edited this page Apr 24, 2017 · 3 revisions

Code-style UI.Windows

Common

namespaceMW2.Gameplay.Scene{publicclassHeroView:DatabaseMonoItem<HeroView>{publicfloatparam1;publicintparam2;privateAnyTypeparamPrivate1;privateAnyTypeparamPrivate2;privateboolanyProperty{get;privateset;}publicvoidMethod(intparam1,intparam2,boolparam3=false){this.param1=param1;this.param2=param2;if(param3==true)this.DoSomething();}publicvoidDoSomething(){Debug.LogFormatted("{0}, {1}",this.param1,this.param2);}}}

Холивар на тему скобок.

Я привык писать скобки {} в конце строки. Объяснить причину этого не могу, это привычка.

if (...) {
// something
}

Пустые строки в начале и в конце нужны исключительно для быстрого чтения кода.

Сравнения с null и bool

Каждый метод, который возвращает bool или переменная, которая является bool, должны описываться полностью. Не допускается сокращение, не указывающее сравнение с true или false. Тоже самое касается и проверки на null.

if (a == true) xxx
if (b == null) xxx

Холивар на тему однострочных if

if (...) xxx

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

Такая запись нужна для быстрого однострочного комментирования и избежания лишних строк:

if (this.image1 != null) this.image1.Recycle();
if (this.image2 != null) this.image2.Recycle();

В коде необходимы такие проверки довольно часто.

Холивар на тему property

Все названия переменных объявляются с маленькой буквы. Property не исключение. Пример для понимания:

this.Setup(this.Something);

В данном примере я должен быстро понять, что Something - это ссылка на метод, а не значение свойства. Сомнительным минусом такого подхода является тот факт, что я не могу отличить property от field. Но я считаю, что раз property не может принимать параметров при обращении, то это тот же field. Более того, я стараюсь избегать объявлений property вообще. Лучше объявите метод ;)

Холивар на тему this

Слово this используется везде в классе для обращения к переменным класса (и базовых) и вызова методов. Это удобно когда не нужно тратить время на придумывание названий для переменных.

public float value;
public float Set(float value) {
this.value = value;
}

Плюсом такого подхода является быстрое прочтение кода и понимание того, где объявлена эта переменная - вне метода или внутри метода.

Static

Все static переменные должны вызываться с указанием имени класса где они объявлены

class A {
public static int param = 12;
void Method() {
Debug.Log(A.param);
}
}

Const

Константы объявляются большими буквами. Обращение должно быть такое же как и к static.

public const int PARAM_SOMETHING_LONG = 123;

return когда и где

В идеале слово return должно употребляться единожды в методе.

private int Method() {
var result = 123;
if (...) {
result = 234;
}
return result;
}

Объявление переменных

У float постфикс должен быть f. У double - d. Это обязательно.

По возможности всегда использовать var - запись будет занимать меньше места. Но иногда для понимания (или по другим причинам) нужно использовать конкретный тип данных.

Объявление переменных списком (float a, b;) является нежелательным.

var v = new Vector3(1f, 2f, 3f);

i++ или ++i

Почти всегда нам нужно просто прибавить единицу и результат исходного выражения нам не важен. Поэтому используем ++i. Исключением может быть только обращение к массиву вроде такого:

array[i++] = 1;
array[i++] = 2;
array[i++] = 3;

Enum

Всегда объявляем enum с указанием типа данных:

public enum Type : byte {
A,
B,
C,
}

После последнего элемента ставим запятую, чтобы быстрее добавлять новые элементы.

Наследование от типа данных необходимо ввиду некоторых проблем, связанных с кастом enum в string при использовании enum в качестве key в типе Dictionary. Это выделает память под строку при каждом поиске.

Boxing/unboxing

Желательно использовать классы шаблонов и шаблонные вызовы методов. Исключения бывают очень редки и object используется крайне редко.

TODO

Когда уже прокинуты события в гуе, необходимо реализовать каждый метод. Но методов много и реализовывать их можно долго - в каждом пишем // TODO. Желательно с комментарием. Также TODO пишем везде, где алгоритм может быть реализован лучше. Потом это сократит работу.

Объявление методов

При объявлении методов пишется сначала scope, а затем static, virtual, override. Само название метода начинается с большой буквы.

public static void Method() {}

Важно понимать, что важнее scope. Если метод недоступен (например, private), то static он или нет уже не важно.

Также независимо от scope обязательно его указание:

private void Method() {
}

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

Вызов методов

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

this.gameObject.SetActive(active: true);
this.image.SetStates(mainState: true, otherState: false, value: 5f);

Editor-функциональность

Вся функциональность, которую хочется делать исключительно в Editor'е должна находиться в ifdef'е UNITY_EDITOR. Таким образом этот код никогда не попадет в прод версию.

#if UNITY_EDITOR
public override void OnValidateEditor() {
base.OnValidateEditor();
if (this.gameObject.activeSelf == false) return;
if (this.image == null) this.image = this.GetComponent<Image>();
if (this.rawImage == null) this.rawImage = this.GetComponent<RawImage>();
}
#endif

Заключение

Если следовать вышеописанным правилам, то можно научиться читать распечатанный кусок кода, оторванный от контекста.