Transform Inspector – Part 2

As I’ve said on the previous iteration of the transform inspector; the second main reason I wrote a custom implementation was to give me access to hidden components on the game object (something which I usually refer to as Entity but that’s a discussion for another post).

It’s not a terribly complicated process. Done in a few steps; Gather all components found on the transform’s owner then display them is a comfortable way and allow users to manipulate their hide flags. See, simple.

Let’s code!

The first thing we’re going to do, as before, is set up the basic display behaviour. In this case we want users to toggle the component view on/off.

public static class InspectHiddenComponents
{
  public static bool Show;

  public static void Perform(GameObject entity)
  {
    Show = EditorGUILayout.Foldout(Show, "Hidden Components");
    if (!Show)
      return;
  }
}

Next we want to actually see the components as they are presented in the game object; I also indent the list to keep in line with the inspection standards. Note that the component list is generated WITHOUT the transform since, well, it doesn’t like it. For one, hiding the transform will mean we lose the component display and will not be able to show it again. And secondly, as I’ve discovered, calling the layout utility on the component under inspection does some funny things to Unity.

public static class InspectHiddenComponents
{
  public static bool Show;

  public static void Perform(GameObject entity)
  {
    Show = EditorGUILayout.Foldout(Show, "Hidden Components");
    if (!Show)
      return;

    EditorGUI.indentLevel += 1;           
    
    var components = entity.GetComponents();
    components = components.Where(item => item.GetType() != typeof (Transform));
    foreach (var component in components)
    {
      var component_name = component.GetType().Name;
      var component_hidden = false;
      component_hidden = EditorGUILayout.Toggle(component_name, component_hidden);
    }
    
    EditorGUI.indentLevel -= 1;
  }
}

And finally we want to update each component’s flags field to comply with the user’s request.

public static class InspectHiddenComponents
{
  public static bool Show;

  public static void Perform(GameObject entity)
  {
    Show = EditorGUILayout.Foldout(Show, "Hidden Components");
    if (!Show)
      return;

    EditorGUI.indentLevel += 1;           
    
    var components = entity.GetComponents();
    components = components.Where(item => item.GetType() != typeof (Transform));
    foreach (var component in components)
    {
      var component_name = component.GetType().Name;
      var component_hidden = component.hideFlags == HideFlags.HideInInspector;;
      component_hidden = EditorGUILayout.Toggle(component_name, component_hidden);
      component.hideFlags = component_hidden ? HideFlags.HideInInspector : HideFlags.None
    }
    
    EditorGUI.indentLevel -= 1;
  }
}

And that’s it. Just call this function in the transform inspector. And we’re done.

We scanned the skies with rainbow eyes and saw machines of every shape and size. We talked with tall Venusians passing through.

Posted in Uncategorized | Tagged , , , , | Leave a comment

Transform Inspector

Yes. Yes I did. I wrote my own transform inspector to use instead of Unity’s built-in version. Why? For several reasons. First, I wanted to be able to easily switch between global/local data display. And secondly, I wanted to see and perform operations on hidden components in the entity (I could have written a new editing-only component to allow me this but I decided that the best place will be on the Transform display itself).

So let’s get to it. First, global/local information. To switch between these views we’ll need to save which view we’re currently on. Could use a boolean. Better to write an enum.

public enum ObjectSpace
{
  Local = 0,
  Global = 1,
}

Now let’s create our basic transform inspector.

[CustomEditor(typeof(Transform))]
public static class TransformInspector
  : UnityEditor.Editor
{
  public static ObjectSpace Space;

  public override void OnInspectorGUI()
  {
    Space = (ObjectSpace) EditorGUILayout.EnumPopup("Space", Space);
  }
}

With that simple concept out of the way. We now need to actually inspect our values based on the selected space. For that we’ll need to retrieve the correct data given some space value. So let’s create a utility for that (For brevity’s sake I’ll just operate on positions).

public static class GetPosition
{
  public static Vector3 Perform(Transform transform, ObjectSpace space)
  {
    switch (space)
    {
      case ObjectSpace.Local: return transform.localPosition;
      case ObjectSpace.Global: return transform.position;
      default: throw new NotImplementedException();
    }
  }
}

Let’s inspect our positions.

[CustomEditor(typeof(Transform))]
public static class TransformInspector
  : UnityEditor.Editor
{
  public static ObjectSpace Space;

  public override void OnInspectorGUI()
  {
    Space = (ObjectSpace) EditorGUILayout.EnumPopup("Space", Space);
    
    var transform = (Transform) target;
    var position = EditorGUILayout.InspectVector3("Position", GetPosition.Perform(transform, Space));
  }
}

Not too shabby. Now we do the same but instead of getting positions based on space we set position based on space.

public static class SetPosition
{
  public static Transform Perform(Transform transform, Vector3 value, ObjectSpace space)
  {
    switch (space)
    {
      case ObjectSpace.Local: transform.localPosition = value; break;
      case ObjectSpace.Global: transform.position = value; break;
      default: throw new NotImplementedException();
    }
    return transform;
  }
}

As for why I’m returning the transform? Just following some advice from the wonderful Effective C++ where were we? Ah yeah. Setting positions.

[CustomEditor(typeof(Transform))]
public static class TransformInspector
  : UnityEditor.Editor
{
  public static ObjectSpace Space;

  public override void OnInspectorGUI()
  {
    Space = (ObjectSpace) EditorGUILayout.EnumPopup("Space", Space);
    
    var transform = (Transform) target;
    var position = EditorGUILayout.InspectVector3("Position", GetPosition.Perform(transform, Space));
    SetPosition.Perform(transform, position, Space);
  }
}

Simple. Extend this for rotations and scale (remember, in Unity only local scale can be set).
Eh, this post is a bit longer than I expected. So I’ll separate it into two. The next post will describe the hidden components inspection.

“There was music in the cafés at night, And revolution in the air”

Posted in Uncategorized | Tagged , , , | Leave a comment

Reset Transform Data

(This post is sort of reposted from Gamasutra although with some modifications).

After a week or so of using the engine I started noticing some tasks which I repeatedly needed but had no built-in support for. One of those was an easy way of resetting the local data of transforms during editing. It’s not hard to achieve and I wrote a simple menu item to do it.

public static class ResetSelectedTransforms
{
  [MenuItem("Utilities/Reset Selected Transforms &z")]
  public static void Perform()
  {
    foreach (var selected in Selection.gameObjects)
    {
      var transform = selected.transform;
      transform.localPosition = Vector3.zero;
      transform.localRotation = Quaternion.identity;
      transform.localScale = Vector3.one;
    }
  }
}

Notice that I added the ‘&z’ character to the menu item’s name; this causes Unity to associate the ‘alt+z’ shortcut to our menu and makes it easier to call it (remember: lazy is good!). And finally see that we’re resetting only the local properties of the transform, this way we’re avoiding a host of issues concerning the parenting hierarchy of the object.

Using this menu item a few times and writing more code for the game I also found that resetting transforms is something I need to do sometimes during Unity’s runtime environment (rather than just while editing – more on my building process and separation of projects in a later post). So let’s extract this into a useful utility/extension method.

public static class TransformResetExtensions
{
  public static void ResetLocal(this Transform transform)
  {
    transform.localPosition = Vector3.zero;
    transform.localRotation = Quaternion.identity;
    transform.localScale = Vector3.one;
  }

  public static void ResetGlobal(this Transform transform)
  {
    transform.position = Vector3.zero;
    transform.rotation = Quaternion.identity;
    // Unity hasn't exposed a setting on the lossy scale;
  }
}
“Truth is I haven’t played much since the baby came in June, but give me half a minute and I’ll get this fiddle back in tune.”
Posted in Uncategorized | Tagged , , , , | Leave a comment

Counterintuitive

(reposted from Gamasutra; so context might be a bit off as we were in the middle of a little war over here).

In between a war and a hard place life goes on and code is written. But since I’m not in the happiest mood to write something constructive I’ll complain. And what shall I complain about, oh great and noble sir or madam? What a silly question… Unity of course.

Let us imagine a game object. An entity if you please. And let us call it, um, I don’t know, “Amir”. Let us delve deeper into the mysteries of creation and attach three other entities to “Amir” (parenting if you will). We shall dub these, “Rob”, “Bob” and, eh, “Slob”. Why not?

To each of these strange and wonderful objects we’ll endeavour to attach a single component called “Health”. Now, four entities, four components. Let me paint you a picture. A simple one, of hard lines and boxes. Of the UML persuasion.

uml

Pop quiz, hotshot.

Amir.GetComponentsInChildren<Health>()

How many components have we got?

My wife’s (who is both amazing and wonderful) first reaction was:

“Are you really going to teach me programming at ten at night?”

I proceeded to get a notepad and she sighed, resigned. Her second reaction, after a quick sketch.

“Three”

And if that wasn’t your first reaction you should probably think long and hard about life in general… Of course if that was your first reaction you probably haven’t been working with Unity for very long either.

“Ah ha!” I exclaimed loudly, “You would think so!”. Then hung my head, “But the answer is four”.

I’ll end this post with a quote from the Unity’s documentation page.
Returns all components of Type [type] in the GameObject or any of its children.

Why? F*** if I knew…

Hey mister if you want to walk on water, would you drop a line my way
Posted in Uncategorized | Tagged , , | Leave a comment

2D Scene View – Reset

This is going to be a fairly short post. Nothing overly complicated but, hopefully, useful.

Long before Unity3D had built-in 2D capabilities (not that the current 2D implementation is overly helpful) it was too easy to accidentally move the scene camera and toss things out of alignment. Now, I know that fixing the scene to a particular plane and orthographic view can easily be achieved via the little scene gizmo at the top/left of the editing window, this action also requires mouse movement and at least a few button clicks. I prefer hotkeys for common operations. Not to mention that having things available through code allows greater control overall.

The steps to achieve this are not complicated.

  • Get the current scene view.
  • Set scene view to orthographic.
  • Rotate scene view to correct angle.
  • Expend scene view to a comfortable size.

that last step is there because Unity has a tendency of zooming in too close to things when performing the camera reset. The comfortable size value itself can be experimented with in order to achieve your own needs.

[MenuItem(MenuName.UtilityItems + "Reset Scene View" + Hotkey.CtrlShift.L)]
public static void Perform()
{
  var current = SceneView.currentDrawingSceneView;
  current.orthographic = true;
  current.rotation = Quaternion.Euler(0.0f, 0.0f, 0.0f);
  current.size = 2000.0f;
}

The menu item attribute might bear a little more explaining but that’ll have to wait for another post.

I guess the winter makes you laugh a little slower, Makes you talk a little lower about the things you could not show her…
Posted in Uncategorized | Tagged , , , , | Leave a comment

First Post

With this blog I’m going to curtail my enthusiasm for terrible puns using the post titles; though I can’t promise to always succeed.

So, why am I starting a new blog?

The short answer is, I want to organize my thoughts concerning all Unity3D things in a single place rather than have them clutter up my main blog every few posts and breaking the flow of other code.

The long answer. Well, there is no long answer. The short answer is actually quite sufficient.

Over the last year or so I also wrote up a bunch of posts over at Gamasutra; but some recent events and frankly a ridiculous waiting period for each post have seeded doubt in my mind about the longevity of anyone’s blogs over there. And I’ll be migrating those over into this site.

But before we begin, let me just say hello to You. Yes, you! The nebulous reader, the most fantastic creature, stumbling in to gaze upon the following posts in search of wisdom, entertainment and maybe some code. Let me just clear it up right now. I… eh, I’m not really sure what I’m doing to be honest, but I promise to have fun while doing it 😀

Oh, yeah, and most of my posts are going end with a quote from either the current song I’m listening to or some song that I like.

With that out of the way and without further ado, let’s start.

Pick and choose, sit and lose, all you different crews, chicks and dudes, who you think is really kickin’ tunes?
Posted in Uncategorized | Leave a comment