Unity3D – Save Your In-Play Transform Modifications (1 of 2)

Don’t you hate it when you’ve made a few changes to your game objects but can’t save them? Perhaps you’ve lined up a couple objects perfectly … but when you press STOP, you know you’ll lose all those modifications and have to re-enter them manually.

Well, not anymore!

playNote: This is an advanced tutorial, recommended for those already familiar with the Unity3D game engine.

Unity3D’s “play mode” is great because it allows you to view your game in-editor. But when you’re done, any modifications that you’ve made to your scene are lost forever. Fair enough, this functionality makes sense. That is, if your game logic or physics system moves your game objects around, you want everything to reset for the next time you press Play.

But what about when you want to save your changes?

The trouble is, often you’ve moved something in your game when testing and you do want to save the location, orientation, and scale. It’d be really convenient to make those changes permanent… but most of us just end up keeping track of them in a text editor or on a scratch piece of paper, only to re-enter the same values a few moments later.

saveloadIn this tutorial, I’ll show you how to create a set of buttons in the Inspector window, allowing you to save (in Play Mode) and then reload any transform (in Edit Mode) on any game object.

To do this, we need to create is a Custom Editor for the Unity Transform. Custom Editors are great because they allow you to implement your own custom inspector for all Game Objects of a particular type, in this case “typeof(Transform)“.

Since this is a UnityEditor script, you’ll want to add the appropriate namespace (using UnityEditor;) and also save the script to a folder titled “Editor” to ensure it is not included in your final build.

As an example, create the following C# file, named: /Editor/keepTransformEditor.cs in your Assets folder.

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

[CustomEditor(typeof(Transform))]
public class keepTransformEditor : UnityEditor.Editor
{
  //...
}

At this point, normally we would just add DrawDefaultInspector() to our own implementation of the OnInspectorGUI() function, like this:


    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();
        if (GUILayout.Button("Save"))
        {
            //... Some Magic Code
        }
    }

But if we do that, we’ll get a Transform that looks like this (see below). The discerning eye should notice that it doesn’t quite look like the Transform editor we know and love.:

Not The Default Inspector You're Looking For

Not The Default Inspector You’re Looking For

After a quick Google search, you’ll find that the DrawDefaultInspector() function for Transform does not in fact, draw the Default Inspector for the Transform. (.. er, it does, but the one we know is not the actually the default)

Thanks, Unity.

So, some nice folks on the Internets posted this close approximation to the actual default Inspector:


    public void DrawABetterInspector(Transform t)
    {
        // Replicate the standard transform inspector gui        
        EditorGUIUtility.labelWidth = 25;
        EditorGUIUtility.fieldWidth = 50;

        EditorGUI.indentLevel = 0;
        Vector3 position = EditorGUILayout.Vector3Field("Position", t.localPosition);
        Vector3 eulerAngles = EditorGUILayout.Vector3Field("Rotation", t.localEulerAngles);
        Vector3 scale = EditorGUILayout.Vector3Field("Scale", t.localScale);
        
        EditorGUIUtility.labelWidth = 0;
        EditorGUIUtility.fieldWidth = 0;

        if (GUI.changed)
        {
            Undo.RecordObject(t, "Transform Change");

            t.localPosition = FixIfNaN(position);
            t.localEulerAngles = FixIfNaN(eulerAngles);
            t.localScale = FixIfNaN(scale);
        }
    }

    private Vector3 FixIfNaN(Vector3 v)
    {
        if (float.IsNaN(v.x))
        {
            v.x = 0.0f;
        }
        if (float.IsNaN(v.y))
        {
            v.y = 0.0f;
        }
        if (float.IsNaN(v.z))
        {
            v.z = 0.0f;
        }
        return v;
    }

Which we can now call via our implementation of OnInspectorGUI():


    public override void OnInspectorGUI()
    {
        Transform t = (Transform)target;

        DrawABetterInspector(t);

        if (GUILayout.Button("Save"))
        {
            //... Some Magic Code
        }

    }

So that’s a lot of code to get us back to square one…

The rest of the code is continued on Unity3D – Save Your In-Play Transform Modifications (2 of 2).

2D Graphics Programming for Games [book] ThumbnailFor more topics on 2D graphics programming, be sure to check out my book, 2D Graphics Programming for Games available now both online and through your favorite independent bookseller.

Leave a Reply