Unity3D tips and tricks
Было уже несколько статей подобного плана, где рассказывались разные трюки и приёмы для Unity. Что-то было совсем очевидно и только для новичков, что-то для более продвинутых товарищей. Хочу внести свою скромную лепту.
Когда проект маленький это не актуально, но когда проект большой и над ним работает много человек можно забыть, за что именно отвечает та или иная переменная, которую задаешь в редакторе. Правильное именование помогает лишь частично, так как слишком короткое. Можно конечно писать Custom Editor и там делать подсказки для каждого типа, но для каждого класса это слишком накладно. Следующий способ позволяет решить такую задачу. Для этого мы делаем 2 классика:
TooltipAttribute.cs
using UnityEngine;
public class TooltipAttribute: PropertyAttribute { public readonly string text; public TooltipAttribute (string text) { this.text = text; } } TooltipDrawer.cs
#if UNITY_EDITOR using UnityEditor; using UnityEngine;
[CustomPropertyDrawer (typeof (TooltipAttribute))] public class TooltipDrawer: PropertyDrawer { public override void OnGUI (Rect position, SerializedProperty prop, GUIContent label) { var atr = (TooltipAttribute) attribute; var content = new GUIContent (label.text, atr.text); EditorGUI.PropertyField (position, prop, content); } } #endif Теперь, если нам надо чтобы в стандартном инспекторе была подсказка по нужной нам переменной — просто делаем так:
[Tooltip («Первоначальный цвет объекта»)] public Color color;
[Tooltip («Скорость объекта, если отрицательная — движется задним ходом»)] public float speed; Результат: На скриншоте почему-то не видно курсора мышки, подсказка появляется при наведении.
Перфекционисты, чтобы не добавлять мусор в релизный код, могут делать так:
#if UNITY_EDITOR [Tooltip («Скорость объекта, если отрицательная — движется задним ходом»)] #endif public float speed; Хотя, на мой взгляд, это уже излишне.
Теперь, даже если через год-два надо что-то подправить в редакторе Вы быстро вспомните что это за переменная.
Вот здесь есть самурайская коллекция PropertyDrawer. Комменты на японском языке, но в принципе всё понятно.
Иногда бывает необходимо проверить наличие значения у переменной. Ну например вот так:
public class Character: MonoBehaviour { Vector3 targetPosition; void MoveTowardsTargetPosition () { if (targetPosition!= Vector3.zero) { //Move towards the target position! } } public void SetTargetPosition (Vector3 newPosition) { targetPosition = newPosition; } } Но что, если нашему герою надо прийти в точку (0, 0, 0)? Тогда такой код не подходит.
Надо использовать nullable type. Просто добавляем знак '?' в конце к типу, и чтобы проверить наличие используем HasValue, а чтобы получить значение — Value.
public class Character: MonoBehaviour { //Notice the added »?» Vector3? targetPosition; void MoveTowardsTargetPosition () { if (targetPosition.HasValue) { //Move towards the target position! //use targetPosition.Value for the actual value } } public void SetTargetPosition (Vector3 newPosition) { targetPosition = newPosition; } }
Этот хинт может пригодится для отладки AI, по крайней мере в моём случае это было так. Смысл хинта совсем прост — просто чтобы не рыть огромный общий лог заводим каждому юниту персональный, в нашем случае это строка (string localLog). Все важные события из жизни монстра пишем туда, а для просмотра надо просто выделить монстра в редакторе. Код для того, чтобы отображался персональный лог в инспекторе:
using UnityEngine; using System.Collections; using UnityEditor;
[CustomEditor (typeof (Monster))] public class MonsterEditor: Editor { Vector2 scrollPos = new Vector2(0, Mathf.Infinity);
public override void OnInspectorGUI () { serializedObject.Update (); Monster monster = (Monster)target;
if (Application.isPlaying) { scrollPos = GUILayout.BeginScrollView ( scrollPos, GUILayout.Height (250)); GUILayout.Label (monster.localLog); GUILayout.EndScrollView ();
if (GUILayout.Button («Clear»)) monster.localLog = »; }
serializedObject.ApplyModifiedProperties (); DrawDefaultInspector (); } } Вот, в общем то, и всё. Теперь мы видим всё что монстр думал про нас и других монстров. Такой вот простой хинт облегчает отладку.
Буду рад, если кому-то это поможет.