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

Code-style UI.Windows

Common

namespace MW2.Gameplay.Scene {

	public class HeroView : DatabaseMonoItem<HeroView> {

		public float param1;
		public int param2;

		private AnyType paramPrivate1;
		private AnyType paramPrivate2;
		
		private bool anyProperty {
			get;
			private set;
		}

		public void Method(int param1, int param2, bool param3 = false) {

			this.param1 = param1;
			this.param2 = param2;

			if (param3 == true) this.DoSomething();

		}

		public void DoSomething() {

			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

Заключение

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