Unity3D tips and tricks

Published on October 07, 2014

Unity3D tips and tricks



    There have already been several articles of this kind, which described various tricks and tricks for Unity. Something was quite obvious and only for beginners, something for more advanced comrades. I want to make my modest contribution.


    1. Tips on variables.



    When the project is small this is not relevant, but when the project is large and a lot of people work on it, you can forget what exactly this or that variable that you set in the editor is responsible for. Proper naming helps only partially, as it is too short. You can certainly write a Custom Editor and there you can make tips for each type, but for each class it is too expensive. The following method allows us to solve such a problem. To do this, we make 2 classics:

    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
    


    Now, if we need a hint in the standard inspector for the variable we need, we simply do this:

    	[Tooltip("Первоначальный цвет объекта")]
    	public Color color;
    	[Tooltip("Скорость объекта, если отрицательная - движется задним ходом")]
    	public float speed;
    


    Result:

    For some reason, the mouse cursor is not visible in the screenshot; a hint appears when you hover.

    Perfectionists, in order not to add garbage to the release code, can do this:
    #if UNITY_EDITOR
    	[Tooltip("Скорость объекта, если отрицательная - движется задним ходом")]
    #endif
    	public float speed;
    


    Although, in my opinion, this is already unnecessary.

    Now, even if in a year or two you need to correct something in the editor, you quickly remember what kind of variable it is.

    Here is the Samurai PropertyDrawer collection. Comments in Japanese, but basically everything is clear.

    2. Nullable types



    Sometimes it is necessary to check if a variable has a value. Well, for example, like this:

    public class Character : MonoBehaviour 
    {
        Vector3 targetPosition;
        void MoveTowardsTargetPosition()
        {
            if(targetPosition != Vector3.zero)
            {
                //Move towards the target position!
            }
        }
        public void SetTargetPosition(Vector3 newPosition)
        {
            targetPosition = newPosition;
        }
    }
    


    But what if our hero needs to come to the point (0, 0, 0)? Then this code does not work.

    You must use the nullable type. Just add the '?' at the end of the type, and to check for availability, use HasValue, and to get the value, use 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;
        }
    }
    


    3. Personal Log.



    This hint can come in handy for debugging AI, at least in my case it was. The meaning of the hint is quite simple - just so as not to dig a huge general log, we make each unit personal, in our case it is a string (string localLog). We write all the important events from the life of a monster there, and for viewing you just need to select a monster in the editor. Code for displaying a personal log in the inspector:

    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();
    	}
    }
    


    That, in general, is all. Now we see everything that the monster thought about us and other monsters. Such a simple hint makes debugging easier.

    I would be glad if this helps someone.