Sponsored By

Featured Blog | This community-written post highlights the best of what the game industry has to offer. Read more like it on the Game Developer Blogs.

Locking Unity - Part 2

In which we get to see the end result of our locking mechanism and I get to write more code.

Amir Barak, Blogger

June 1, 2014

4 Min Read

We left off on a bit of a low note. Sure our locking system locks our entities when we add the TransformLock component but all it does is force it into the scene's origin. We can do better than that. Clearly we need a way to lock/free the transform's position values. Since we want to have different combinations of locked/freed values we'll need to set up enumerated flags.

[Flags]
public enum VectorComponents
{
  None = 0,
  X = 1 << 0,
  Y = 1 << 1,
  Z = 1 << 2,
  XY = X | Y,
  XZ = X | Z,
  YZ = Y | Z,
  XYZ = X | Y | Z,
}


Couple of things to note; bit twiddling means I don't have to remember the base 10 representation of the binary bits and I've already created the flag combinations because it's a small enough range and it means less typing later. And the following extension allows us to query whether a given flag value has another particular value in it.

public static class VectorComponentsExtensions
{
  public static bool Contains(this VectorComponents current, VectorComponents value)
  {
    return (current & value) == value;
  }
}


Next we add the flags as a field in the component.

public class TransformLock
  : MonoBehaviour
{
   public VectorComponents Components = VectorComponents.None;
   public Vector3 Saved;
}


And finally we need to update the inspector to make the data useful. In order to do that we should define what it is that the system needs to do for us. First we want to be able to change the enum flags (this is easily done via Unity's own EditorGUILayout). Secondly we want to make sure that whenever a flag has been set for a particular component we update that component's saved value. Lastly, we want to keep replacing the transform's position values which are locked with those of the saved data. Let's get to it.

[CustomEditor(typeof(TransformLock))]
public class TransformLockInspector
 : UnityEditor.Editor
{
  public TransformLock Lock { get { return (TransformLock) target; } }

  public void OnSceneGUI()
  {
    var position = Lock.transform.localPosition;
    if (Lock.Components.Contains(VectorComponents.X))
      position.x = Lock.Saved.x;

    if (Lock.Components.Contains(VectorComponents.Y))
       position.y = Lock.Saved.y;

    if (Lock.Components.Contains(VectorComponents.Z))
       position.z = Lock.Saved.z;

    Lock.transform.localPosition = position;
  }

  public override void OnInspectorGUI()
  {
    var new_value = InspectComponentsEnum();
    if (Lock.Components == new_value)
      return;

    if (ShouldUpdateComponent(new_value, VectorComponents.X))
      Lock.Saved.x = Lock.transform.localPosition.x;

    if (ShouldUpdateComponent(new_value, VectorComponents.Y))
      Lock.Saved.y = Lock.transform.localPosition.y;

    if (ShouldUpdateComponent(new_value, VectorComponents.Z))
      Lock.Saved.z = Lock.transform.localPosition.z;

     Lock.Components = new_value;
  }
}


Our custom inspection method;

public VectorComponents InspectComponentsEnum()
{
    return (VectorComponents) EditorGUILayout.EnumPopup("Components", Lock.Components);
}


And the last method for querying whether a saved component should be re-set;

public bool ShouldUpdateComponent(VectorComponents value, VectorComponents component)
{
   return (!Lock.Components.Contains(component) && value.Contains(component))
}


That's it. The position lock system works. Try it. It's fun. This approach is also applicable to both the rotation and scale data of the Transform component. Personally I also implemented the system for locking parents and names of entities and I have, obviously, more tools written up to make the process easier to read and perform through code (specialized extensions for setting/getting positions, refactored classes for handling enum management, etc). But those particular implementations I'll leave aside for now. Anyway, hope it was interesting and, as usual, if you've got a better way or just some pointers (heh, oh god, that's a terrible joke) feel free to comment!

She is something all together different, never just an ordinary girl.

Read more about:

Featured Blogs

About the Author(s)

Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like