Website may be up and down over next few months. I'm currently doing a complete overhaul of everything. Going back to simple individual .htm pages, new overall site theme, sanitizing and cleaning up html of all pages and blog posts, attempting to implement a new tooling and publishing system etc etc.

When writing editor scripts involving EditorWindow’s it is often important to initialize and cleanup your code when the window is shown and hidden. Specifically it is important to differentiate between the OnDisable and OnDestroy methods if you need to perform some kind of cleanup before the window is closed or disposed of. OnDestroy is called when the user closes the window, where as OnDisable is called after unity recompiles scripts. Think of the OnDestroy method as a close event for the window but the window still resides in memory, where the OnDisable method signals that the window is about to be unloaded from memory such as during a script recompile.

This differentiation is important when you need to save data to disk before the window is destroyed during a recompile. OnDestroy will not get called during recompile only OnDisable does. The OnEnable method is typically intended as a initialization method where you can load data related to the window.

I only wish the Unity team had made these methods more descriptive ala .NET window forms naming scheme. OnDestroy & OnDisable are not the most descriptive for what they do as well as being somewhat similar in spelling. But I digress.


A simple performance test for comparing direct file property access or creating a FileInfo object.

The results show that if you are accessing more then one file property FileInfo is the way to go otherwise File.GetCreationTime and related methods have the same performance hit.

100 iterations of c:\windows
directValues –> 00:00:00.2900065
infoValues –> 00:00:00.1611554

void Main()
{
    var folder = "c:\\windows";
    var files = Directory.GetFiles(folder, "*.*", SearchOption.TopDirectoryOnly);

    var stopwatch = new Stopwatch();
    var directValues = 0l;
    var infoValues = 0l;
    for (int i = 0; i < 100; i++)
    {
        stopwatch.Restart();
        stopwatch.Start();
        foreach (var file in files)
        {
            var lastWriteTime = File.GetLastWriteTime(file);
            var creationTime = File.GetCreationTime(file);
        }

        stopwatch.Stop();
        directValues += stopwatch.ElapsedTicks;

        stopwatch.Restart();
        stopwatch.Start();
        foreach (var file in files)
        {
            var info = new FileInfo(file);
            var lastWriteTime = info.LastWriteTime;
            var creationTime = info.CreationTime;
        }

        stopwatch.Stop();
        infoValues += stopwatch.ElapsedTicks;

    }

    "100 iterations of c:\\windows".Dump();
    TimeSpan.FromTicks(directValues).Dump("directValues");
    TimeSpan.FromTicks(infoValues).Dump("infoValues");
}

When compiling your Unity games & applications to different platforms, there may be times when you need to get the location of special folder locations on the system that your app is running on.

The Environment.GetFolderPath method can be use to retrieve those specific folder locations. Below is a list of folder locations for both Windows 7 and Mac OS X. The source of this information is available here along with code examples.


Desktop (0)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname/Desktop
Windows7.gif Windows 7 C:\Users\yourname\Desktop

Programs (2)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Users\yourname\AppData\Roaming\Microsoft\Windows\Start Menu\Programs

Personal (5)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname
Windows7.gif Windows 7 C:\Users\yourname\Documents

MyDocuments (5)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname
Windows7.gif Windows 7 C:\Users\yourname\Documents

Favorites (6)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname/Library/Favorites
Windows7.gif Windows 7 C:\Users\yourname\Favorites

Startup (7)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Users\yourname\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

Recent (8)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Users\yourname\AppData\Roaming\Microsoft\Windows\Recent

SendTo (9)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Users\yourname\AppData\Roaming\Microsoft\Windows\SendTo

StartMenu (11)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Users\yourname\AppData\Roaming\Microsoft\Windows\Start Menu

MyMusic (13)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname/Music
Windows7.gif Windows 7 C:\Users\yourname\Music

DesktopDirectory (16)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname/Desktop
Windows7.gif Windows 7 C:\Users\yourname\Desktop

MyComputer (17)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 n/a

Templates (21)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname/Templates
Windows7.gif Windows 7 C:\Users\yourname\AppData\Roaming\Microsoft\Windows\Templates

ApplicationData (26)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname/.config
Windows7.gif Windows 7 C:\Users\yourname\AppData\Roaming

LocalApplicationData (28)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/username/.local/share (inside unity)
/Applications/Unity/MonoDevelop.app/Contents/MacOS/../Frameworks/Mono.framework/Versions/Current/share
Windows7.gif Windows 7 C:\Users\yourname\AppData\Local

InternetCache (32)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname/Library/Caches
Windows7.gif Windows 7 C:\Users\yourname\AppData\Local\Microsoft\Windows\Temporary Internet Files

Cookies (33)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Users\yourname\AppData\Roaming\Microsoft\Windows\Cookies

History (34)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Users\yourname\AppData\Local\Microsoft\Windows\History

CommonApplicationData (35)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /usr/share
Windows7.gif Windows 7 C:\ProgramData

System (37)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Windows\system32

ProgramFiles (38)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Applications
Windows7.gif Windows 7 C:\Program Files
or C:\Program Files (x86)

MyPictures (39)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) /Users/yourname/Pictures
Windows7.gif Windows 7 C:\Users\yourname\Pictures

CommonProgramFiles (43)
Apple.gif Mac OS X 10.6.8 (Snow Leopard) n/a
Windows7.gif Windows 7 C:\Program Files\Common Files
or C:\Program Files (x86)\Common Files

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

I recently came across a strange behavior while loading text resource assets. In particular the Resources.LoadAll method does not accept Path.DirectorySeparatorChar characters in a path. In fact it only accepts Path.AltDirectorySeparatorChar characters. This behavior is different then standard .net file/folder methods that accept either Path.AltDirectorySeparatorChar or Path.DirectorySeparatorChar without distinction. What this means is that you can’t directly use Path.Combine to build a path and pass it to the Resources.LoadAll method you first have to replace any Path.DirectorySeparatorChar characters with Path.AltDirectorySeparatorChar characters.

The documentation for Resources.Load also does not mention this behavior.

I have submitted a bug report here –> https://fogbugz.unity3d.com/default.asp?533268_jgvrk2lbu1qm398e

    using System.IO;

    using UnityEditor;

    using UnityEngine;

    /// <summary>
    /// Handles settings registration.
    /// </summary>
    [InitializeOnLoad]
    public class EditorInitialization
    {
        /// <summary>
        /// Holds a value indicating whether the RunCallbacks method has been called at least once before.
        /// </summary>
        private static bool ranOnce;

        /// <summary>
        /// Initializes static members of the <see cref="EditorInitialization"/> class.
        /// </summary>
        static EditorInitialization()
        {
            EditorApplication.update += RunCallbacks;
        }

        private static void RunCallbacks()
        {
            if (!ranOnce)
            {
                // try to load resource
                var path = Path.Combine("Test/SubFolder", "testfile"); // result is Test/SubFolder\testfile

                // var data = Resources.LoadAll("Test/SubFolder/testfile", typeof(TextAsset)); // this line is successful
                var data = Resources.LoadAll(path, typeof(TextAsset));  // this line fails

                if (data != null && data.Length != 0)
                {
                    Debug.Log("found it");
                }
                else
                {
                    Debug.Log("not found! " + path);
                }

                ranOnce = true;
                return;
            }

            // do stuff 
        }
    }

Did you know that you can manipulate a game objects collider in the scene view by holding down the 'Shift' key. Holding shift will display the colliders control dots. Just drag the dots to adjust the collider!


Unity 101 Tip #11 - Snap to vertex

Published 6/17/2012 by createdbyx in News | Unity
Tags: ,

Hold the 'V' key while the translate tool is active and you can drag an object by it's vertices and snap that vertex to another objects vertex!


Unity 101 Tip #10 - Inspector lock

Published 6/16/2012 by createdbyx in News | Unity
Tags: ,

The inspector window contains a small lock icon in the top right of the window. If you select a game object and click the lock the inspector will be locked to that object and will not change when you select other objects. Click again to disable the lock. This allows you to have multiple instector windows open with locks to different objects.


You can visually tag your game objects with icons by selecting the object and clicking the Red/Green/Blue colored cube in the upper left of the inspector window.

You can select a colored Label, Dot, or a Texture from your assets.


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