-
-
Save belzecue/387d6e98b91ba1ec5b2ee97727655613 to your computer and use it in GitHub Desktop.
Tool for aligning and distribute objects, primarly in 2d space, can be extended to 3d
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using UnityEditor; | |
using System.Collections.Generic; | |
/// <summary> | |
/// Tool for spacing objects, primarly in 2d space, can be extended to 3d | |
/// </summary> | |
public class ObjectSpacing : EditorWindow | |
{ | |
[MenuItem ("Hello/ObjectSpacing/Open Window")] | |
static void OpenWindow () | |
{ | |
ObjectSpacing window = (ObjectSpacing)EditorWindow.GetWindow (typeof(ObjectSpacing)); | |
window.minSize = new Vector2 (100, 30); | |
window.Show (); | |
} | |
Texture[] _icon_distribute; | |
Texture[] icon_distribute { | |
get { | |
if (_icon_distribute == null) { | |
_icon_distribute = new Texture[2]; | |
_icon_distribute [0] = AssetDatabase.LoadAssetAtPath<Texture2D> ("Assets/Gists/Tools/Editor/distribute-x.png"); | |
_icon_distribute [1] = AssetDatabase.LoadAssetAtPath<Texture2D> ("Assets/Gists/Tools/Editor/distribute-y.png"); | |
} | |
return _icon_distribute; | |
} | |
} | |
void OnGUI () | |
{ | |
List<GameObject> objects = new List<GameObject> (Selection.gameObjects); | |
int count = objects.Count; | |
//GUILayout.Label ("Distribute evenly", EditorStyles.boldLabel); | |
GUILayout.BeginHorizontal (); | |
EditorGUI.BeginDisabledGroup (count < 2); | |
for (int axis = 0; axis < 2; ++axis) { | |
GUILayout.BeginVertical (); | |
EditorGUILayout.LabelField (" " + GetInterval(axis, objects), GUILayout.MaxWidth (60)); | |
if (icon_distribute [axis] == null) { | |
if (GUILayout.Button (axisName [axis].ToString(), GUILayout.MaxWidth (28))) { | |
DistributeByAxis (axis); | |
} | |
} else { | |
if (GUILayout.Button (icon_distribute [axis], GUILayout.MaxWidth (28))) { | |
DistributeByAxis (axis); | |
} | |
} | |
GUILayout.EndVertical (); | |
} | |
//GUILayout.Label ("Distribute by number", EditorStyles.boldLabel); | |
GUILayout.BeginHorizontal (); | |
for (int axis = 0; axis < 2; ++axis) { | |
GUILayout.BeginVertical (); | |
//if (axis == 0) { | |
alignment [axis] = GUILayout.HorizontalSlider (alignment [axis], 0, 1); | |
// } else { | |
// alignment [axis] = GUILayout.VerticalSlider (alignment [axis], 1, 0); | |
// } | |
distance [axis] = EditorGUILayout.FloatField (distance [axis]); | |
if (GUILayout.Button ("Spread " + axisName [axis])) { | |
DistributeByAxis (axis, distance [axis], alignment [axis]); | |
} | |
GUILayout.EndVertical (); | |
} | |
GUILayout.EndHorizontal (); | |
EditorGUI.EndDisabledGroup (); | |
GUILayout.EndHorizontal (); | |
} | |
Vector3 alignment = Vector3.zero; | |
float GetInterval(int axis, List<GameObject> objects){ | |
int count = objects.Count; | |
if (count < 2) | |
return 0; | |
objects.Sort ((a, b) => a.transform.position [axis].CompareTo (b.transform.position [axis])); | |
float min = objects [0].transform.position [axis]; | |
float max = objects [count - 1].transform.position [axis]; | |
float interval = (max - min) / (float)(count - 1); | |
return interval; | |
} | |
static string axisName = "xyz"; | |
Vector3 distance = Vector3.one * 10; | |
[MenuItem ("Hello/ObjectSpacing/Vertical")] | |
static void SpaceVertical () | |
{ | |
DistributeByAxis (1); | |
} | |
[MenuItem ("Hello/ObjectSpacing/Horizontal")] | |
static void SpaceHorizontal () | |
{ | |
DistributeByAxis (0); | |
} | |
[MenuItem ("Hello/ObjectSpacing/Vertical And Horizontal")] | |
static void SpaceVerticalAndHorizontal () | |
{ | |
DistributeByAxis (0); | |
DistributeByAxis (1); | |
} | |
static void DistributeByAxis (int axis) | |
{ | |
List<GameObject> objects = new List<GameObject> (Selection.gameObjects); | |
int count = objects.Count; | |
if (count < 2) | |
return; | |
Undo.RecordObjects (Selection.gameObjects, "ObjectSpacing axis " + axis); | |
objects.Sort ((a, b) => a.transform.position [axis].CompareTo (b.transform.position [axis])); | |
float min = objects [0].transform.position [axis]; | |
float max = objects [count - 1].transform.position [axis]; | |
float interval = (max - min) / (float)(count - 1); | |
//Debug.Log ("Count " + count); | |
for (int i = 0; i < count; ++i) { | |
var p = objects [i].transform.position; | |
p [axis] = min + (i * interval); | |
objects [i].transform.position = p; | |
} | |
} | |
static void DistributeByAxis (int axis, float interval, float align) | |
{ | |
List<GameObject> objects = new List<GameObject> (Selection.gameObjects); | |
int count = objects.Count; | |
if (count < 2) | |
return; | |
objects.Sort ((a, b) => a.transform.position [axis].CompareTo (b.transform.position [axis])); | |
Undo.RecordObjects (Selection.gameObjects, "ObjectSpacing axis " + axis); | |
float min = objects [0].transform.position [axis]; | |
float max = objects [count-1].transform.position [axis]; | |
float alignCenter = Mathf.Lerp (min, max, align); | |
float distance = interval * (count - 1); | |
float start = alignCenter - distance * (align); | |
for (int i = 0; i < count; ++i) { | |
var p = objects [i].transform.position; | |
p [axis] = start + (i * interval); | |
objects [i].transform.position = p; | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment