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!


Source (adapted for GenericImage) -> http://stackoverflow.com/a/11176961/341706

/// <summary>
        /// Rotates the image.
        /// </summary>
        /// <param name="image">
        /// The source image to rotate.
        /// </param>
        /// <param name="angle">
        /// The angle in degrees to rotate the image.
        /// </param>
        /// <param name="centerX">The x position of the rotation axis.</param>
        /// <param name="centerY">The y position of the rotation axis.</param>
        /// <returns>
        /// Returns a new rotated image.
        /// </returns>
        public static GenericImage<T> Rotate<T>(this GenericImage<T> image, int centerX, int centerY, float angle)
        {
            // source (adapted for GenericImage) -> http://stackoverflow.com/a/11176961/341706
            var radians = (Math.PI / 180) * angle;
            var cos = Math.Cos(radians);
            var sin = Math.Sin(radians);
            var newImage = new GenericImage<T>(image.Width, image.Height);

            for (var x = 0; x < image.Width; x++)
                for (var y = 0; y < image.Height; y++)
                {
                    var m = x - centerX;
                    var n = y - centerY;
                    var j = ((int)(m * cos + n * sin)) + centerX;
                    var k = ((int)(n * cos - m * sin)) + centerY;
                    if (j >= 0 && j < image.Width && k >= 0 && k < image.Height)
                    {
                        newImage[x, y] = image[j, k];
                    }
                }

            return newImage;
        }

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\""

Source -> http://stackoverflow.com/questions/10322341/simple-algorithm-for-drawing-filled-ellipse-in-c-c

/// <summary>
        /// Draws a filled Ellipse.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="x">
        /// The x left most position of the ellipse.
        /// </param>
        /// <param name="y">
        /// The y top most position of the ellipse.
        /// </param>
        /// <param name="width">
        /// The width of the ellipse.
        /// </param>
        /// <param name="height">
        /// The height of the ellipse.
        /// </param>
        /// <param name="color">
        /// The color to use.
        /// </param>
        public static void FillEllipse<T>(this GenericImage<T> image, int x, int y, int width, int height, T color)
        {
            width = width / 2;
            height = height / 2;
            var centerX = x + width;
            var centerY = y + height;

            // source -> http://stackoverflow.com/questions/10322341/simple-algorithm-for-drawing-filled-ellipse-in-c-c
            for (var indexY = -height; indexY <= height; indexY++)
            {
                for (var indexX = -width; indexX <= width; indexX++)
                {
                    var dx = indexX / (double)width;
                    var dy = indexY / (double)height;
                    if (dx * dx + dy * dy <= 1)
                    {
                        image[centerX + indexX, centerY + indexY] = color;
                    }
                }
            }
        }

Source (converted from C++) -> http://www.dailyfreecode.com/Code/draw-ellipse-midpoint-ellipse-algorithm-714.aspx

/// <summary>
        /// Draws a Ellipse.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="centerX">
        /// The x center position of the circle.
        /// </param>
        /// <param name="centerY">
        /// The y center position of the circle.
        /// </param>
        /// <param name="width">
        /// The width of the Ellipse.
        /// </param>
        /// <param name="height">
        /// The height of the Ellipse.
        /// </param>
        /// <param name="color">
        /// The color to use.
        /// </param>
        public static void DrawEllipse<T>(this GenericImage<T> image, int centerX, int centerY, int width, int height, T color)
        {
            // source (converted from C++) -> http://www.dailyfreecode.com/Code/draw-ellipse-midpoint-ellipse-algorithm-714.aspx
            float aa = (width * width);
            float bb = (height * height);
            float aa2 = (aa * 2);
            float bb2 = (bb * 2);

            float x = 0;
            float y = height;

            float fx = 0;
            float fy = (aa2 * height);

            float p = (int)(bb - (aa * height) + (0.25 * aa) + 0.5);

            image[(int)(centerX + x), (int)(centerY + y)] = color;
            image[(int)(centerX + x), (int)(centerY - y)] = color;
            image[(int)(centerX - x), (int)(centerY - y)] = color;
            image[(int)(centerX - x), (int)(centerY + y)] = color;

            while (fx < fy)
            {
                x++;
                fx += bb2;

                if (p < 0) p += (fx + bb);

                else
                {
                    y--;
                    fy -= aa2;
                    p += (fx + bb - fy);
                }

                image[(int)(centerX + x), (int)(centerY + y)] = color;
                image[(int)(centerX + x), (int)(centerY - y)] = color;
                image[(int)(centerX - x), (int)(centerY - y)] = color;
                image[(int)(centerX - x), (int)(centerY + y)] = color;
            }

            p = (int)((bb * (x + 0.5) * (x + 0.5)) + (aa * (y - 1) * (y - 1)) - (aa * bb) + 0.5);

            while (y > 0)
            {
                y--;
                fy -= aa2;

                if (p >= 0) p += (aa - fy);

                else
                {
                    x++;
                    fx += bb2;
                    p += (fx + aa - fy);
                }

                image[(int)(centerX + x), (int)(centerY + y)] = color;
                image[(int)(centerX + x), (int)(centerY - y)] = color;
                image[(int)(centerX - x), (int)(centerY - y)] = color;
                image[(int)(centerX - x), (int)(centerY + y)] = color;
            }
        }


Source -> http://www.dailyfreecode.com/code/fill-circle-scan-line-circle-fill-675.aspx

/// <summary>
        /// Fills a circle.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="centerX">
        /// The x center position of the circle.
        /// </param>
        /// <param name="centerY">
        /// The y center position of the circle.
        /// </param>
        /// <param name="radius">
        /// The radius of the circle.
        /// </param>  
        /// <param name="color">
        /// The color to use.
        /// </param>    
        public static void FillCircle<T>(this GenericImage<T> image, int centerX, int centerY, int radius, T color)
        {
            // source -> http://www.dailyfreecode.com/code/fill-circle-scan-line-circle-fill-675.aspx
            int x1;
            int x2;

            var counter = (centerY + radius);

            for (var count = (centerY - radius); count <= counter; count++)
            {
                x1 = (int)(centerX + Math.Sqrt((radius * radius) - ((count - centerY) * (count - centerY))) + 0.5);
                x2 = (int)(centerX - Math.Sqrt((radius * radius) - ((count - centerY) * (count - centerY))) + 0.5);

                image.DrawLine(x1, count, x2, count, color);
            }
        }


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.


Source (converted from Java) -> http://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#Java

/// <summary>
        /// Draws a circle.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="centerX">
        /// The x center position of the circle.
        /// </param>
        /// <param name="centerY">
        /// The y center position of the circle.
        /// </param>
        /// <param name="radius">
        /// The radius of the circle.
        /// </param>  
        /// <param name="color">
        /// The color to use.
        /// </param>    
        public static void DrawCircle<T>(this GenericImage<T> image, int centerX, int centerY, int radius, T color)
        {
            // source (converted from Java) -> http://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#Java
            var d = (5 - radius * 4) / 4;
            var x = 0;
            var y = radius;

            do
            {
                // ensure index is in range before setting (depends on your image implementation)
                // in this case we check if the pixel location is within the bounds of the image before setting the pixel
                image[centerX + x, centerY + y] = color;
                image[centerX + x, centerY - y] = color;
                image[centerX - x, centerY + y] = color;
                image[centerX - x, centerY - y] = color;
                image[centerX + y, centerY + x] = color;
                image[centerX + y, centerY - x] = color;
                image[centerX - y, centerY + x] = color;
                image[centerX - y, centerY - x] = color;
                if (d < 0)
                {
                    d += 2 * x + 1;
                }
                else
                {
                    d += 2 * (x - y) + 1;
                    y--;
                }
                x++;
            } while (x <= y);
        }


Source (converted from C) -> http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C

/// <summary>
        /// Draws a line on an <see cref="GenericImage{T}"/>.
        /// </summary>
        /// <param name="image">
        /// The destination image.
        /// </param>
        /// <param name="x1">
        /// The x position for the start of the line.
        /// </param>
        /// <param name="y1">
        /// The y position for the start of the line.
        /// </param>
        /// <param name="x2">
        /// The x position for the end of the line.
        /// </param>
        /// <param name="y2">
        /// The y position for the end of the line.
        /// </param>
        /// <param name="color">
        /// The color that the line will be drawn with.
        /// </param>
        public static void DrawLine<T>(this GenericImage<T> image, int x1, int y1, int x2, int y2, T color)
        {
            // source (converted from C) -> http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C
            int dx = Math.Abs(x2 - x1), sx = x1 < x2 ? 1 : -1;
            int dy = Math.Abs(y2 - y1), sy = y1 < y2 ? 1 : -1;
            int err = (dx > dy ? dx : -dy) / 2;

            for (; ; )
            {
                image[x1, y1] = color;
                if (x1 == x2 && y1 == y2) break;
                int e2 = err;
                if (e2 > -dx) { err -= dy; x1 += sx; }
                if (e2 < dy) { err += dx; y1 += sy; }
            }
        }

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