以下内容是根据Unity 2020.1.0f1版本进行编写的

1、目的

日常使用UGUI时,经常有需要把某个GameObject往上/下/左/右移动一个像素或10个像素的需求,每次改都要一个个选中然后改Pos的值,因此想写个小工具方便处理。

2、实现

本质上是写一个RectTransform类的Editor类,并继承自RectTransformEditor,难点在于RectTransformEditor是内部类,不能继承,需要用反射拿出来。
这个问题其实问AI就可以了,AI给出的答案也比较简单和清晰。

直接上完整代码:

using UnityEngine;
using UnityEditor;
using System;
using System.Reflection;

[CanEditMultipleObjects]
[CustomEditor(typeof(RectTransform),true)]
public class RectTransformExtend : Editor
{
	private Editor defaultEditor;  // 存储默认编辑器实例

	public RectTransformExtend ()
	{
	}

    private void OnEnable()
    {
		// 通过反射创建默认RectTransformEditor实例
		Type rectTransformEditorType = Type.GetType("UnityEditor.RectTransformEditor, UnityEditor");
		if (rectTransformEditorType != null)
		{
			defaultEditor = Editor.CreateEditor(targets, rectTransformEditorType);
		}
	}

    public override void OnInspectorGUI()
	{
		// 绘制默认的RectTransform界面
		if (defaultEditor != null)
		{
			MethodInfo onInspectorGUI = defaultEditor.GetType().GetMethod("OnInspectorGUI", BindingFlags.Public | BindingFlags.Instance);
			onInspectorGUI?.Invoke(defaultEditor, null);
		}

		GUILayout.BeginVertical();
		GUILayout.BeginHorizontal();
		if (GUILayout.Button("↑10"))
		{
			MovePos(new Vector3(0, 10, 0));
		}
		if (GUILayout.Button ("↑"))
		{
			MovePos(new Vector3(0, 1, 0));
		}
		if (GUILayout.Button("↑20"))
		{
			MovePos(new Vector3(0, 20, 0));
		}
		GUILayout.EndHorizontal ();
		GUILayout.BeginHorizontal ();
		if (GUILayout.Button("←10"))
		{
			MovePos(new Vector3(-10, 0, 0));
		}
		if (GUILayout.Button ("←"))
		{
			MovePos(new Vector3(-1, 0, 0));
		}
		if (GUILayout.Button ("→"))
		{
			MovePos(new Vector3(1, 0, 0));
		}
		if (GUILayout.Button("→10"))
		{
			MovePos(new Vector3(10, 0, 0));
		}
		GUILayout.EndHorizontal ();
		GUILayout.BeginHorizontal();
		if (GUILayout.Button("↓10"))
		{
			MovePos(new Vector3(0, -10, 0));
		}
		if (GUILayout.Button ("↓"))
		{
			MovePos(new Vector3(0, -1, 0));
		}
		if (GUILayout.Button("↓20"))
		{
			MovePos(new Vector3(0, -20, 0));
		}
		GUILayout.EndHorizontal();
		GUILayout.EndVertical ();
	}

	public void MovePos(Vector3 vertor)
    {
		foreach (var obj in targets)
        {
			RectTransform rectTrans = (RectTransform)obj;
			rectTrans.localPosition = rectTrans.localPosition + vertor;
			Undo.RecordObject(obj, "move RectTransform 1px");
			EditorUtility.SetDirty(obj);
		}
	}
}

和上面说的一样,就是用反射获取到RectTransformEditor这个类,然后在OnInspectorGUI方法中添加所需的按钮和对应方法即可。我这里还支持了多选操作和撤销

3、效果

GIF

 posted on 2025-08-06 15:40  chj一诺千金  阅读(9)  评论(0)    收藏  举报