With the introduction to Unity 5 there comes some api changes. Specifically this foot note was interesting “[2] in Unity5 we also cache the transform component on the c# side, so there should no longer be a performance reason to cache the transform component yourself.

I decided to test it out by writing a few performance test scripts and comparing performance numbers. Below is a screen shot of my results along with the scripts used.

As you can see caching a reference to the transform component in the Start method then using that reference is still faster then calling “this.transform” directly albeit only slightly by about 10-20 ticks. And calling “this.GetComponent<Transform>()” is almost twice as slow.

Unity5TransformPerformance

The code for the PerformanceTesting class is availible here.

TransformCachedGetComponentPerformance script

    using UnityEngine;

    public class TransformCachedGetComponentPerformance : MonoBehaviour
    {
        private Transform reference;

        /// <summary>
        /// Awake is called when the script instance is being loaded.
        /// </summary>
        public void Awake()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Create("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
        }

        /// <summary>
        /// Start is called just before any of the Update methods is called the first time.
        /// </summary>
        public void Start()
        {
            this.reference = this.GetComponent<Transform>();
        }

        /// <summary>
        /// Update is called every frame, if the MonoBehaviour is enabled.
        /// </summary>
        public void Update()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Start("UnityTesting/TransformCachedGetComponentPerformance/Update");      
#endif

            var rnd = new System.Random();
            this.reference.localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));

#if PERFORMANCE
            perf.Stop("UnityTesting/TransformCachedGetComponentPerformance/Update");
#endif
        }
    }

TransformGetComponentPerformance script

    using UnityEngine;

    public class TransformGetComponentPerformance : MonoBehaviour
    {
        /// <summary>
        /// Awake is called when the script instance is being loaded.
        /// </summary>
        public void Awake()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Create("UnityTesting/TransformGetComponentPerformance/Update");
#endif
        }
        
        /// <summary>
        /// Update is called every frame, if the MonoBehaviour is enabled.
        /// </summary>
        public void Update()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Start("UnityTesting/TransformGetComponentPerformance/Update");
#endif

            var rnd = new System.Random();
            this.GetComponent<Transform>().localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));

#if PERFORMANCE
            perf.Stop("UnityTesting/TransformGetComponentPerformance/Update");
#endif
        }
    }

TransformFieldPerformance script

    using UnityEngine;

    public class TransformFieldPerformance : MonoBehaviour
    {
        /// <summary>
        /// Awake is called when the script instance is being loaded.
        /// </summary>
        public void Awake()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Create("UnityTesting/TransformFieldPerformance/Update");
#endif
        }

        /// <summary>
        /// Update is called every frame, if the MonoBehaviour is enabled.
        /// </summary>
        public void Update()
        {
#if PERFORMANCE
            var perf = PerformanceTesting.PerformanceTesting<string>.Instance;
            perf.Start("UnityTesting/TransformFieldPerformance/Update");
#endif

            var rnd = new System.Random();
            this.transform.localPosition = new Vector3(rnd.Next(-3, 3), rnd.Next(-3, 3), rnd.Next(-3, 3));

#if PERFORMANCE
            perf.Stop("UnityTesting/TransformFieldPerformance/Update");
#endif
        }
    }

There are some instances when you may need to lock the mouse cursor to the screen. For example rotating the camera where you would press down on the right mouse button then drag the mouse to rotate the camera. If you wish to hide the mouse cursor and lock it to the screen while dragging you can use Screen.lockCursor.

using UnityEngine;

public class lockCursorExample : MonoBehaviour
{
    void DidLockCursor()
    {
        Debug.Log("Locking cursor");
    }

    void DidUnlockCursor()
    {
        Debug.Log("Unlocking cursor");
    }

    private bool wasLocked;

    void Update()
    {
        if (!Screen.lockCursor && this.wasLocked)
        {
            this.wasLocked = false;
            this.DidUnlockCursor();
        }
        else if (Screen.lockCursor && !this.wasLocked)
        {
            this.wasLocked = true;
            this.DidLockCursor();
        }

        if (Input.GetMouseButtonDown(1))
        {
            Screen.lockCursor = true;
        }

        if (Input.GetMouseButtonUp(1))
        {
            Screen.lockCursor = false;
        }
    }
}

Ever wish you could have a tool tip appear when hovering your mouse over a control in the inspector? Well look no further then Unity’s ToolTip attribute that you can apply to your MonoBehaviour’s fields!

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    [Tooltip("Health value between 0 and 100.")]
    public int health = 0;
}

Sometimes it is handy to keep a game object alive for as long as your game is running. In order to prevent your object from being destroyed when loading a new scene use GameObject.DontDestroyOnLoad and your game object will persist between scene changes.


If you need to retrieve the default Arial font via code at runtime you can do so using the Resources.GetBuiltInResource method.

var font = Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;

If you need to stylize your gui you can use the GUISettings class to change, the cursor color, flash speed, the selection color for text fields, as well as double click behavior.

    public class GuiSettingsExample : MonoBehaviour
    {
        public Color cursorColor;     
        public float flashSpeed;      
        public bool doubleClickSelectWord;       
        public Color selectionColor;             
        public bool tripleCLickLine;             
        private string text = "test string";     
        private Vector2 scroll;                  
        public GUISkin skin;                     

        public void OnGUI()
        {
            GUI.skin = this.skin;
            var settings = GUI.skin.settings;
            settings.cursorColor = this.cursorColor;
            settings.cursorFlashSpeed = this.flashSpeed;
            settings.doubleClickSelectsWord = this.doubleClickSelectWord;
            settings.selectionColor = this.selectionColor;
            settings.tripleClickSelectsLine = this.tripleCLickLine;


            this.scroll = GUILayout.BeginScrollView(this.scroll, false, false, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
            this.text = GUILayout.TextArea(this.text);
            GUILayout.EndScrollView();
        }
    }

Did you know that the GUI class has a matrix property that you can use to rotate and scale your gui elements.

The sample behavior that is provided below will scale and rotate a gui label in the center of the screen.

public class GuiMatrixDemo : MonoBehaviour
{
    private float rotation;

    /// <summary>
    /// OnGUI is called for rendering and handling GUI events.
    /// </summary>
    public void OnGUI()
    {
        var matrix = GUI.matrix;

        GUI.Label(new Rect(5, 5, 100, 20), "before matrix");

        this.rotation += 15f * Time.deltaTime;
        var scale = Mathf.Clamp((float)Math.Sin(Time.time) + 1 * 2, 1, 3);
        GUI.matrix = Matrix4x4.TRS(new Vector3(Screen.width / 2, Screen.height / 2, 0), Quaternion.Euler(0, 0, this.rotation), Vector3.one * scale);
        var size = GUI.skin.label.CalcSize(new GUIContent("test string"));
        var rect = new Rect((-size.x / 2f), (-size.y / 2f), size.x, size.y);
        GUI.Label(rect, "test string");
        GUI.matrix = matrix;
        GUI.Label(new Rect(5, 25, 100, 20), "after matrix");
    }
}

Ever wish you could draw properties for serializable classes and script variables using your own gui logic? Unity 4 introduces the PropertyDrawer base class to do just that!


Not a unity specific tip but still a handy unity helper for creating a unity project from file explorer. *Works only for windows platforms.* Download the CreateUnityProject.reg file below or open up Notepad and paste the snippet below then save the file with a *.reg file extension. Next navigate to the file and right click on it and select “Merge” from the popup menu. You should now be able to create a new unity project by right clicking on a empty folder in File Explorer and selecting “Create unity project”.

CreateUnityProject.reg (488.00 bytes)

CreateUnityProject64.reg (476.00 bytes)

For x86 unity use the snippet below

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Folder\shell\Create unity project]

[HKEY_CLASSES_ROOT\Folder\shell\Create unity project\command]
@="\"C:\\Program Files (x86)\\Unity\\Editor\\unity.exe\" -createProject \"%1\""

For 64bit unity use the snippet below

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Folder\shell\Create unity project]

[HKEY_CLASSES_ROOT\Folder\shell\Create unity project\command]
@="\"C:\\Program Files\\Unity\\Editor\\unity.exe\" -createProject \"%1\""

I came across this article while searching for a way of unit testing my unity GUI windows. A link to the article is available here 50 Tips for Working with Unity (Best Practices). It contains some very sound advice and is well worth the time to read through.


Created by: X

Just another personal website in this crazy online world

Name of author Dean Lunz (aka Created by: X)
Computer programming nerd, and tech geek.
About Me -- Resume