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.

The code below allows you to scale a GameObject transform to a specific size along the x & z axis by taking into account the GameObjects renderer bounds if a renderer component is attached.

/// <summary>
/// Scales a transform to specific dimensions along the x & z axis.
/// </summary>
/// <param name="transform">
/// Reference to the transform to scale.
/// </param>
/// <param name="width">The width along the x axis that represents the target size.</param>
/// <param name="height">The height along the z axis that represents the target size.</param>
public static void ScaleTransform(Transform transform, float width, float height)
{
    // get bounds of the prefab
    var bounds = new Bounds();
    var encapsulate = false;
    if (!Utilities.Helpers.GetBoundWithChildren(transform, ref bounds, ref encapsulate))
    {
        return;
    }

    // get minimum size from the size dimensions
    var min = Mathf.Min(width, height);

    // get the maximum x or z size of the transform
    var max = Mathf.Max(bounds.size.x, bounds.size.z);

    // calculate the scale factor 
    var scaleFactor = min / max;

    // apply scaling to the transform
    transform.localScale *= scaleFactor;
}

/// <summary>
/// Gets the rendering bounds of the transform.
/// </summary>
/// <param name="transform">The game object to get the bounding box for.</param>
/// <param name="pBound">The bounding box reference that will </param>
/// <param name="encapsulate">Used to determine if the first bounding box to be 
/// calculated should be encapsulated into the <see cref="pBound"/> argument.</param>
/// <returns>Returns true if at least one bounding box was calculated.</returns>
public static bool GetBoundWithChildren(Transform transform, ref Bounds pBound, ref bool encapsulate)
{
    var didOne = false;

    // get 'this' bound
    if (transform.gameObject.renderer != null)
    {
        var bound = transform.gameObject.renderer.bounds;
        if (encapsulate)
        {
            pBound.Encapsulate(bound.min);
            pBound.Encapsulate(bound.max);
        }
        else
        {
            pBound.min = bound.min;
            pBound.max = bound.max;
            encapsulate = true;
        }

        didOne = true;
    }

    // union with bound(s) of any/all children
    foreach (Transform child in transform)
    {
        if (GetBoundWithChildren(child, ref pBound, ref encapsulate))
        {
            didOne = true;
        }
    }

    return didOne;
}

Using the Undo.IncrementCurrentEventIndex allows your editor scripts to undo a single action rather then have unity undo many actions that may have occurred in rapid succession. Place the code below into a “Editor” folder for it to run.

The “create object” button will create 10 cubes and call Undo.RegisterCreatedObjectUndo for each of them. Click this button then press ctrl+z to undo all of the objects that were created.

The second button “create single object” will also create 10 cubes but will also call the Undo.IncrementCurrentEventIndex method notifying unity that each object that is created should have a separate undo action. Click “create single object” to create 10 cubes then press ctrl+z to undo each object creation individually.

NOTE: At the time of this writing the unity documentation does not have information on the Undo.IncrementCurrentEventIndex method and searching for it also comes back with zero results.

    using UnityEngine;
    using UnityEditor;

    public class UndoTest : EditorWindow
    {

        public void OnGUI()
        {
            if (GUILayout.Button("create object"))
            {
                this.Create(false);
            }
            if (GUILayout.Button("create single object"))
            {
                this.Create(true);
            }

            GUILayout.Label("use ctrl+z to undo each action");
        }

        private void Create(bool single)
        {
            for (int i = 0; i < 10; i++)
            {
                if (single)
                {
                    Undo.IncrementCurrentEventIndex();
                }

                var obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
                obj.transform.position = new Vector3(Random.Range(-10, 10), Random.Range(-10, 10), Random.Range(-10, 10));

                Undo.RegisterCreatedObjectUndo(obj, "create " + obj.name);
            }
        }

        [MenuItem("CBX/UndoTest")]
        public static void ShowWindow()
        {
            GetWindow<UndoTest>("UndoTest").Show();
        }
    }

/// <summary>
/// Packs color components into a <see cref="uint"/> type.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
/// <returns>Returns a uint representing the color.</returns>
public static uint Pack(int r, int g, int b, int a)
{
    return (((uint)r & 0xff)) | (((uint)g & 0xff) << 8) | (((uint)b & 0xff) << 16) | (((uint)a & 0xff) << 24);
}

/// <summary>
/// Unpacks a <see cref="uint"/> type into a color type.
/// </summary>
/// <param name="value">The packed color value to unpack.</param>
/// <returns>Returns a color type from the unpacked values.</returns>
public static Color Unpack(uint value)
{
    var r = (byte)(value);
    var g = (byte)(value >> 8);
    var b = (byte)(value >> 16);
    var a = (byte)(value >> 24);

    return new Color(r, g, b, a);
}

Today I was writing some C# code where I needed to manage a multidimensional array. Specifically I needed to store a items using Column, Row, & Depth as indexers. Instead I wrote a Array3D class that used generics to store any type and internally it uses a single dimensional array and a little bit of math to select the right index.

Not long after I started writing it Déjà vu set in. You know I could have swore I’ve written this class some time ago. Searching through hundreds of projects and tens of thousands of files dating back to 2001 ala .NET 1.0 I came up with nothing. I even went a little nuts and searched back further into my old Turbo Pascal and QBasic code but still found nothing.

Google, DuckDuckGo, & Bing searches were no help either. I could not shake the feeling I have written or have come across this code before. Maybe not in C# but in some other language. I’m sure I have …

This is not the first time I have started to write code and had a strong sense that I have written this code before as I’m sure many programmers do. Maybe it’s just me but with all our modern fancy IDE’s and add-ons archiving code for long periods of time, as in decades, does not seem to be something that has been readily addressed. If there is one thing I absolutely hate is having to repeat my self to the computer when it comes to coding. it’s also why I have visual studio set to auto save every 60 seconds.

Also hard to believe .NET is pushing 12+ years already. Hard to believe that the so called high tech industry essentially has not changed at all since the early 1960’s. Yes, 1960’s & 70’s that’s the era when the first high level languages were originally developed. And here we are 50+ years later and were still just an endless sea of primates spanking our hands on the keyboard just hoping for the best. But that is a rant for another time. :P

So to try and address the issue of code loss I have decided to start a “Code Snippets” series to archive various code snippets in an effort to make searching for them a little bit easier.


XNA example code updates

Published 2/4/2007 by createdbyx in Example | News | XNA
Tags: , ,

I just purchased a wired xbox 360 controller so I can test my code using the controller! I also just posted updated code for my two xna example projects ...

The examples now support the xbox 360 controller as an input device.


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