using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEditor.EditorTools; namespace TFramework { [EditorTool("AxisTool", typeof(Transform))] public class AxisTool : EditorTool { private GUIContent uIContent; private Transform _target; private List chlids = new List(); private Axis axis = Axis.X; private GUIContent centerConter; public GUIContent CenterConter { get { if (centerConter == null) { centerConter = new GUIContent(); centerConter.image = EditorGUIUtility.IconContent("Grid.MoveTool").image; centerConter.tooltip = "居中所有轴"; } return centerConter; } } public override GUIContent toolbarIcon { get { if (uIContent == null) { uIContent = new GUIContent(); uIContent.tooltip = "AxisTool"; uIContent.image = EditorGUIUtility.IconContent("AvatarPivot").image; } return uIContent; } } private void OnEnable() { ToolManager.activeToolChanged += TargetChangeEvent; Selection.selectionChanged += TargetChangeEvent; } private void TargetChangeEvent() { if (!ToolManager.IsActiveTool(this)) return; _target = target as Transform; chlids.Clear(); foreach (Transform item in _target) { chlids.Add(item); } } private void OnDisable() { ToolManager.activeToolChanged -= TargetChangeEvent; Selection.selectionChanged -= TargetChangeEvent; } public override void OnToolGUI(EditorWindow window) { if (_target == null) return; Rect rect = new Rect(window.position.width - 200, window.position.height - 170, 160, 50); int id = GUIUtility.GetControlID(FocusType.Passive, rect); HandleUtility.AddDefaultControl(id); using (new Handles.DrawingScope()) { EditorGUI.BeginChangeCheck(); Vector3 newPos = Handles.PositionHandle(_target.position, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(_target, "Move Pivot"); Vector3 dir = newPos - _target.position; _target.position = newPos; for (int i = 0; i < chlids.Count; i++) { Undo.RecordObject(chlids[i], "Move Pivot"); chlids[i].position -= dir; } EditorUtility.SetDirty(_target); AssetDatabase.SaveAssets(); } } Handles.BeginGUI(); GUI.Box(rect, "", "Window"); rect.Set(rect.x + 3, rect.y + 3, 20, 20); GUI.Label(rect, "轴"); rect.Set(rect.x + 20, rect.y + 1, 80, 20); axis = (Axis)EditorGUI.EnumPopup(rect, axis); rect.Set(rect.x + 80, rect.y - 1, 20, 20); if (GUI.Button(rect, CenterConter)) { SetAxis(2); } rect.Set(rect.x - 100, rect.y + 23, 50, 20); if (GUI.Button(rect, axis == Axis.Y ? "上" : (axis == Axis.X ? "左" : "前"))) { SetAxis(-1); } rect.Set(rect.x + 50, rect.y, 50, 20); if (GUI.Button(rect, "中")) { SetAxis(0); } rect.Set(rect.x + 50, rect.y, 50, 20); if (GUI.Button(rect, axis == Axis.Y ? "下" : (axis == Axis.X ? "右" : "后"))) { SetAxis(1); } GUI.enabled = true; Handles.EndGUI(); } void SetAxis(int pos) { Bounds bounds = GetBounds(_target); if (pos == 2) { _target.position += bounds.center; foreach (Transform item in _target) { item.position -= bounds.center; } return; } float value = 0; switch (axis) { case Axis.X: value = pos == -1 ? bounds.center.x + bounds.size.x / 2 : (pos == 0 ? bounds.center.x : bounds.center.x - bounds.size.x / 2); _target.position = new Vector3(_target.position.x + value, _target.position.y, _target.position.z); foreach (Transform item in _target) { item.position = new Vector3(item.position.x - value, item.position.y, item.position.z); } break; case Axis.Y: value = pos == -1 ? bounds.center.y + bounds.size.y / 2 : (pos == 0 ? bounds.center.y : bounds.center.y - bounds.size.y / 2); _target.position = new Vector3(_target.position.x, _target.position.y + value, _target.position.z); foreach (Transform item in _target) { item.position = new Vector3(item.position.x, item.position.y - value, item.position.z); } break; case Axis.Z: value = pos == -1 ? bounds.center.z + bounds.size.z / 2 : (pos == 0 ? bounds.center.z : bounds.center.z - bounds.size.z / 2); _target.position = new Vector3(_target.position.x, _target.position.y, _target.position.z + value); foreach (Transform item in _target) { item.position = new Vector3(item.position.x, item.position.y, item.position.z - value); } break; } EditorUtility.SetDirty(_target); AssetDatabase.SaveAssets(); } Bounds GetBounds(Transform target) { Renderer[] renders = target.GetComponentsInChildren(); Bounds bounds = new Bounds(Vector3.zero, Vector3.zero); if (renders.Length == 0) return bounds; Vector3 postion = target.position; Quaternion rotation = target.rotation; Vector3 scale = target.localScale; target.position = Vector3.zero; target.localScale = Vector3.one; Vector3 center = Vector3.zero; foreach (Renderer child in renders) { center += child.bounds.center; } center /= renders.Length; bounds.center = center; foreach (Renderer child in renders) { bounds.Encapsulate(child.bounds); } target.position = postion; target.localScale = scale; return bounds; } enum Axis { X, Y, Z } } }