Skip to content

Instantly share code, notes, and snippets.

@ktpttd
Forked from ttesla/ObjectAligner.cs
Created September 29, 2022 19:19
Show Gist options
  • Select an option

  • Save ktpttd/34beaac96a1873620cbdeb6d57ffbcaa to your computer and use it in GitHub Desktop.

Select an option

Save ktpttd/34beaac96a1873620cbdeb6d57ffbcaa to your computer and use it in GitHub Desktop.
Unity Object Aligner
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace Skeletor
{
/// <summary>
/// This is an alternative object sorter if you strictly require your objects sorted by name.
/// If you use it, name your objects like this:
/// Object_1
/// Object_2
/// Object_3
/// Object_4
/// </summary>
public class NameSorter : IComparer<GameObject>
{
public int Compare(GameObject x, GameObject y)
{
string xName = x.name;
string yName = y.name;
if (xName.Contains("_") && yName.Contains("_"))
{
int a = int.Parse(xName.Split('_')[1]);
int b = int.Parse(yName.Split('_')[1]);
return a - b;
}
else
{
return xName.CompareTo(yName);
}
}
}
/// <summary>
/// Hierarchy sort. Default sorting method.
/// </summary>
public class UnityTransformSort : IComparer<GameObject>
{
public int Compare(GameObject lhs, GameObject rhs)
{
if (lhs == rhs) return 0;
if (lhs == null) return -1;
if (rhs == null) return 1;
return (lhs.transform.GetSiblingIndex() > rhs.transform.GetSiblingIndex()) ? 1 : -1;
}
}
/// <summary>
/// Aligns objects and shift them with the given amount
/// Using hierarchy sort as default but you may use naming sort if you like.
/// </summary>
public class ObjectAligner : EditorWindow
{
private GameObject[] mObjects;
private Vector3 mShiftAmount;
private int mAlignedCount;
private IComparer<GameObject> mNameSorter = new NameSorter();
private IComparer<GameObject> mTransformSorter = new UnityTransformSort();
[MenuItem("Skeletor/Object Aligner #F4")]
static void Init()
{
EditorWindow.GetWindow<ObjectAligner>(false, "Object Aligner");
}
void OnGUI()
{
mObjects = Selection.gameObjects;
mShiftAmount = EditorGUILayout.Vector3Field("Shift Amount:", mShiftAmount);
if (mObjects != null)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Objects:");
Array.Sort(mObjects, mTransformSorter);
foreach (GameObject obj in mObjects)
{
EditorGUILayout.LabelField(obj.name);
}
}
if (GUILayout.Button("Align!", GUILayout.Width(60.0f)))
{
mAlignedCount = 0;
if (mObjects != null && mObjects.Length > 0)
{
for (int i = 0; i < mObjects.Length; i++)
{
mObjects[i].transform.localPosition = mObjects[0].transform.localPosition + mShiftAmount * i;
mAlignedCount++;
}
}
Debug.Log("Aligned! : " + mAlignedCount);
}
if (mAlignedCount > 0)
{
EditorGUILayout.HelpBox("Items aligned: " + mAlignedCount, MessageType.Info);
UpdatePrefab();
}
}
void OnEnable()
{
//Debug.Log("On enable");
}
void OnDisable()
{
//Debug.Log("On Disable");
}
void OnFocus()
{
//Debug.Log("On Focus");
mAlignedCount = 0;
}
void OnLostFocus()
{
//Debug.Log("Lost Focus");
}
public void UpdatePrefab()
{
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
if (prefabStage != null)
{
EditorSceneManager.MarkSceneDirty(prefabStage.scene);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment