Skip to content

Instantly share code, notes, and snippets.

@Naphier
Last active November 5, 2015 04:45
Show Gist options
  • Save Naphier/15ce4686c75b2f652065 to your computer and use it in GitHub Desktop.
Save Naphier/15ce4686c75b2f652065 to your computer and use it in GitHub Desktop.
// First we need an enum for a dropdown to select what to align to (first or last selected).
public AlignToType alignTo = AlignToType.lastSelected;
// We also need an enum to flag what axes we want to align on.
public AxisFlag alignmentAxis;
// This method will display the Alignment options and execution button.
private void AlignmentInspector()
{
// Start off with a nice bold label to help section off the area.
EditorGUILayout.LabelField("Alignment", EditorStyles.boldLabel);
// This creates a dropdown style field where you can only select one item in a list.
alignTo = (AlignToType)EditorGUILayout.EnumPopup("Align to", alignTo);
// This creates a mask field that allows us to select multiple enum values.
alignmentAxis = (AxisFlag)EditorGUILayout.EnumMaskField("Axis", alignmentAxis);
// This will be the base message that shows on our button if no other game object is selected.
// We need to select more than one object so we have something to align to!
string buttonLabel = "Select another object to align to";
// This bool is used to set the state of the button.
// We start off with false since we don't yet know if more than one game object is selected.
bool enableButton = false;
// This gets us an array of the game objects (more specifically, their transforms)
// that are selected in the hierarchy.
Transform[] selectedTransforms = Selection.transforms;
// If there is more than 1 transform selected decide how to label the button
// and set the bool to enable the button.
if (selectedTransforms.Length > 1)
{
// If we have selected "Align to: last selected" in the inspector make
// the label say the name of the last selected transform's game object.
if (alignTo == AlignToType.lastSelected)
{
buttonLabel = "Align to " + selectedTransforms[selectedTransforms.Length - 1].name;
}
else
{
// Otherwise, label the button with the first selected tranform's name.
buttonLabel = "Align to " + selectedTransforms[0].name;
}
enableButton = true;
}
// If we set this then it will disable or enable
// any GUI elements that come after it.
GUI.enabled = enableButton;
// Create the button and if it is pressed call AlignTo().
if (GUILayout.Button(buttonLabel))
{
AlignTo(alignTo, alignmentAxis);
}
// Don't forget to make sure all GUI elements are enabled after this point.
GUI.enabled = true;
}
// This method takes each selected transform and aligns it to either the first or last
// selected transform along the axes selected.
private void AlignTo(AlignToType to , AxisFlag axis)
{
// Get the array of selected transforms.
Transform[] selectedTransforms = Selection.transforms;
// Define the target transform's index as 0.
// This can be used as the selectedTransforms array index
// if we're aligning to the first selected.
int targetIndex = 0;
// If we're not aligning to the first selected we need to
// use the last index in the array.
if (to == AlignToType.lastSelected)
targetIndex = selectedTransforms.Length - 1;
// Iterate through the array and apply the new positions when necessary.
for (int i = 0; i < selectedTransforms.Length; i++)
{
// If the index is the index of our target transform then
// no need to do anything since it doesn't need to move.
if (i == targetIndex)
continue;
// Temporarily store the position of the transform that we'll be moving
// so that we can modify its x,y, or z value independently.
Vector3 temp = selectedTransforms[i].position;
// Here's where we use a bitwise operator, &, to check if we should move along this axis.
// What this says is: Does the "axis" flag parameter contain AxisFlag.x?
// If it does then set the temp's x position to the target's x position.
if ((axis & AxisFlag.X) == AxisFlag.X)
temp.x = selectedTransforms[targetIndex].position.x;
// If the "axis" flag parameter contains AxisFlag.y then translate on the y axis to the target.
if ((axis & AxisFlag.Y) == AxisFlag.Y)
temp.y = selectedTransforms[targetIndex].position.y;
// Now do the same on the Z axis.
if ((axis & AxisFlag.Z) == AxisFlag.Z)
temp.z = selectedTransforms[targetIndex].position.z;
// Now we record the current state of the transform before we move it.
Undo.RecordObject(selectedTransforms[i], selectedTransforms[i].name + " aligned to " + selectedTransforms[targetIndex].name);
// Finally we can move the transform to its new position.
selectedTransforms[i].position = temp;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment