Gamasutra: The Art & Business of Making Gamesspacer
View All     RSS
September 23, 2014
arrowPress Releases
September 23, 2014
PR Newswire
View All





If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 
Locking Unity - Part 2
by Amir Barak on 06/01/14 04:59:00 pm   Featured Blogs

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

 

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.

Related Jobs

InnoGames GmbH
InnoGames GmbH — Hamburg, Germany
[09.23.14]

Mobile Developer C++ (m/f)
Raven Software / Activision
Raven Software / Activision — Madison, Wisconsin, United States
[09.23.14]

Sr. Gameplay Engineer - Raven
Raven Software / Activision
Raven Software / Activision — Madison, Wisconsin, United States
[09.23.14]

Lead Engineer - Raven
Square Enix Co., Ltd.
Square Enix Co., Ltd. — Tokyo, Japan
[09.22.14]

Programmers






Comments



none
 
Comment: