【Unity3D编辑器开发】Unity3D中实现Transform组件拓展,快速复制、粘贴、复原【非常实用】

推荐阅读

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

在开发中,常常会遇到频繁复制粘贴物体的坐标、旋转、缩放的操作。

使用Unity自带的组件复制粘贴比较麻烦:
复制:

粘贴:

还有一些需要复制位置、旋转、缩放的值到到代码中,如果一个一个复制粘贴非常麻烦,还要一些需要复制添加自定义文本,也很不方便。

所以,就开发了一个小工具,来提升开发效率。

二、正文

2-1、实现快速复制/粘贴,位置/旋转/缩放功能

效果图:

在Editor文件夹中新建脚本,随便命名,然后编辑代码:

csharp 复制代码
using UnityEngine;
using UnityEditor;
using System.Text;
using static UnityEditor.IMGUI.Controls.PrimitiveBoundsHandle;
using static UnityEngine.UI.Image;

[CanEditMultipleObjects]
[CustomEditor(typeof(Transform), true)]
public class TransformEditor : Editor
{
    static public TransformEditor instance;

    //当前的本地坐标
    SerializedProperty mPos;
    //当前的本地旋转
    SerializedProperty mRot;
    //当前的本地缩放
    SerializedProperty mScale;

    void OnEnable()
    {
        instance = this;

        if (this)
        {
            try
            {
                var so = serializedObject;
                mPos = so.FindProperty("m_LocalPosition");
                mRot = so.FindProperty("m_LocalRotation");
                mScale = so.FindProperty("m_LocalScale");
            }
            catch { }
        }
    }

    void OnDestroy() { instance = null; }

    /// <summary>
    /// Draw the inspector widget.绘制inspector小部件。
    /// </summary>
    public override void OnInspectorGUI()
    {
        //设置label的宽度
        EditorGUIUtility.labelWidth = 15f;

        serializedObject.Update();

        DrawPosition();
        DrawRotation();
        DrawScale();
        DrawCopyAndPaste();

        serializedObject.ApplyModifiedProperties();
    }


    void DrawCopyAndPaste()
    {
        GUILayout.BeginHorizontal();
        bool reset = GUILayout.Button("Copy");
        bool reset2 = GUILayout.Button("Paste");
        GUILayout.EndHorizontal();

        if (reset)
        {
            //把数值打印出来
            var select = Selection.activeGameObject;
            if (select == null)
                return;
            //Debug.Log(select.name+"("+ mPos.vector3Value.x.ToString()+ ","+ mPos.vector3Value.y.ToString() + ","+ mPos.vector3Value.z.ToString() + ")");
            //Debug.Log(select.name + mRot.quaternionValue);
            //Debug.Log(select.name + "(" + mScale.vector3Value.x.ToString() + "," + mScale.vector3Value.y.ToString() + "," + mScale.vector3Value.z.ToString() + ")");

            StringBuilder s = new StringBuilder();
            s.Append("TransformInspector_" + "(" + mPos.vector3Value.x.ToString() + "," + mPos.vector3Value.y.ToString() + "," + mPos.vector3Value.z.ToString() + ")" + "_");
            s.Append(mRot.quaternionValue + "_");
            s.Append("(" + mScale.vector3Value.x.ToString() + "," + mScale.vector3Value.y.ToString() + "," + mScale.vector3Value.z.ToString() + ")");
            //添加到剪贴板
            UnityEngine.GUIUtility.systemCopyBuffer = s.ToString();
        }
        if (reset2)
        {
            //把数值打印出来
            //Debug.Log(UnityEngine.GUIUtility.systemCopyBuffer);
            string s = UnityEngine.GUIUtility.systemCopyBuffer;
            string[] sArr = s.Split('_');
            if (sArr[0] != "TransformInspector")
            {
                Debug.LogError("未复制Transform组件内容!Transform component content not copied!");
                return;
            }
            //Debug.Log("Pos:" + sArr[1]);
            //Debug.Log("Rot:" + sArr[2]);
            //Debug.Log("Scale:" + sArr[3]);
            try
            {
                mPos.vector3Value = ParseV3(sArr[1]);
                mRot.quaternionValue = new Quaternion() { x = ParseV4(sArr[2]).x, y = ParseV4(sArr[2]).y, z = ParseV4(sArr[2]).z, w = ParseV4(sArr[2]).w };
                mScale.vector3Value = ParseV3(sArr[3]);
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
                return;
            }

        }
    }
    /// <summary>
    /// String To Vector3
    /// </summary>
    /// <param name="strVector3"></param>
    /// <returns></returns>
    Vector3 ParseV3(string strVector3)
    {
        strVector3 = strVector3.Replace("(", "").Replace(")", "");
        string[] s = strVector3.Split(',');
        return new Vector3(float.Parse(s[0]), float.Parse(s[1]), float.Parse(s[2]));
    }
    /// <summary>
    /// String To Vector4
    /// </summary>
    /// <param name="strVector4"></param>
    /// <returns></returns>
    Vector4 ParseV4(string strVector4)
    {
        strVector4 = strVector4.Replace("(", "").Replace(")", "");
        string[] s = strVector4.Split(',');
        return new Vector4(float.Parse(s[0]), float.Parse(s[1]), float.Parse(s[2]), float.Parse(s[3]));
    }
    #region Position 位置
    void DrawPosition()
    {
        GUILayout.BeginHorizontal();
        EditorGUILayout.PropertyField(mPos.FindPropertyRelative("x"));
        EditorGUILayout.PropertyField(mPos.FindPropertyRelative("y"));
        EditorGUILayout.PropertyField(mPos.FindPropertyRelative("z"));
        bool reset = GUILayout.Button("P", GUILayout.Width(20f));

        GUILayout.EndHorizontal();

        if (reset) mPos.vector3Value = Vector3.zero;
    }
    #endregion
    #region Scale 缩放
    void DrawScale()
    {
        GUILayout.BeginHorizontal();
        {
            EditorGUILayout.PropertyField(mScale.FindPropertyRelative("x"));
            EditorGUILayout.PropertyField(mScale.FindPropertyRelative("y"));
            EditorGUILayout.PropertyField(mScale.FindPropertyRelative("z"));
            bool reset = GUILayout.Button("S", GUILayout.Width(20f));
            if (reset) mScale.vector3Value = Vector3.one;
        }
        GUILayout.EndHorizontal();
    }
    #endregion
    #region Rotation is ugly as hell... since there is no native support for quaternion property drawing 旋转是丑陋的地狱。。。因为四元数属性绘图没有本地支持
    enum Axes : int
    {
        None = 0,
        X = 1,
        Y = 2,
        Z = 4,
        All = 7,
    }

    Axes CheckDifference(Transform t, Vector3 original)
    {
        Vector3 next = t.localEulerAngles;

        Axes axes = Axes.None;

        if (Differs(next.x, original.x)) axes |= Axes.X;
        if (Differs(next.y, original.y)) axes |= Axes.Y;
        if (Differs(next.z, original.z)) axes |= Axes.Z;
        return axes;
    }

    Axes CheckDifference(SerializedProperty property)
    {
        Axes axes = Axes.None;

        if (property.hasMultipleDifferentValues)
        {
            Vector3 original = property.quaternionValue.eulerAngles;

            foreach (Object obj in serializedObject.targetObjects)
            {
                axes |= CheckDifference(obj as Transform, original);
                if (axes == Axes.All) break;
            }
        }
        return axes;
    }

    /// <summary>
    /// Draw an editable float field. 绘制可编辑的浮动字段。
    /// </summary>
    /// <param name="hidden">Whether to replace the value with a dash 是否将值替换为破折号</param>
    /// <param name="greyedOut">Whether the value should be greyed out or not 值是否应灰显</param>
    static bool FloatField(string name, ref float value, bool hidden, GUILayoutOption opt)
    {
        float newValue = value;
        GUI.changed = false;

        if (!hidden)
        {
            newValue = EditorGUILayout.FloatField(name, newValue, opt);
        }
        else
        {
            float.TryParse(EditorGUILayout.TextField(name, "--", opt), out newValue);
        }

        if (GUI.changed && Differs(newValue, value))
        {
            value = newValue;
            return true;
        }
        return false;
    }

    /// <summary>
    /// Because Mathf.Approximately is too sensitive.因为数学近似值太敏感了。
    /// </summary>
    static bool Differs(float a, float b) { return Mathf.Abs(a - b) > 0.0001f; }

    /// <summary>
    /// 注册Undo
    /// </summary>
    /// <param name="name"></param>
    /// <param name="objects"></param>
    static public void RegisterUndo(string name, params Object[] objects)
    {
        if (objects != null && objects.Length > 0)
        {
            UnityEditor.Undo.RecordObjects(objects, name);

            foreach (Object obj in objects)
            {
                if (obj == null) continue;
                EditorUtility.SetDirty(obj);
            }
        }
    }

    /// <summary>
    /// 角度处理
    /// </summary>
    /// <param name="angle"></param>
    /// <returns></returns>
    static public float WrapAngle(float angle)
    {
        while (angle > 180f) angle -= 360f;
        while (angle < -180f) angle += 360f;
        return angle;
    }

    void DrawRotation()
    {
        GUILayout.BeginHorizontal();
        {
            Vector3 visible = (serializedObject.targetObject as Transform).localEulerAngles;

            visible.x = WrapAngle(visible.x);
            visible.y = WrapAngle(visible.y);
            visible.z = WrapAngle(visible.z);

            Axes changed = CheckDifference(mRot);
            Axes altered = Axes.None;

            GUILayoutOption opt = GUILayout.MinWidth(30f);

            if (FloatField("X", ref visible.x, (changed & Axes.X) != 0, opt)) altered |= Axes.X;
            if (FloatField("Y", ref visible.y, (changed & Axes.Y) != 0, opt)) altered |= Axes.Y;
            if (FloatField("Z", ref visible.z, (changed & Axes.Z) != 0, opt)) altered |= Axes.Z;
            bool reset = GUILayout.Button("R", GUILayout.Width(20f));

            if (reset)
            {
                mRot.quaternionValue = Quaternion.identity;
            }
            else if (altered != Axes.None)
            {
                RegisterUndo("Change Rotation", serializedObject.targetObjects);

                foreach (Object obj in serializedObject.targetObjects)
                {
                    Transform t = obj as Transform;
                    Vector3 v = t.localEulerAngles;

                    if ((altered & Axes.X) != 0) v.x = visible.x;
                    if ((altered & Axes.Y) != 0) v.y = visible.y;
                    if ((altered & Axes.Z) != 0) v.z = visible.z;

                    t.localEulerAngles = v;
                }
            }
        }
        GUILayout.EndHorizontal();
    }
    #endregion
}

运行结果:

这样就实现了基本的快速复制/粘贴,位置/旋转/缩放功能。

接下来,就实现单独的位置、旋转、缩放的复制和粘贴吧。

2-2、单独的位置、旋转、缩放的赋值粘贴功能

效果图:

示例代码:

csharp 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEngine;

public class ButtonHandler
{
    public string showDescription;
    public Action onClickCallBack;
    public ButtonHandler(string showDescription, Action onClickCallBack)
    {
        this.showDescription = showDescription;
        this.onClickCallBack = onClickCallBack;
    }
}
[CanEditMultipleObjects]
[CustomEditor(typeof(Transform))]
public class TransformEditor2 : Editor
{
    static public Editor instance;

    private bool extensionBool;

    ButtonHandler[] buttonHandlerArray;

    //当前的本地坐标
    SerializedProperty mPos;
    //当前的本地旋转
    SerializedProperty mRot;
    //当前的本地缩放
    SerializedProperty mScale;


    private void OnEnable()
    {
        instance = this;

        var editorType = Assembly.GetAssembly(typeof(Editor)).GetTypes().FirstOrDefault(m => m.Name == "TransformInspector");
        instance = CreateEditor(targets, editorType);

        if (this)
        {
            try
            {
                var so = serializedObject;
                mPos = so.FindProperty("m_LocalPosition");
                mRot = so.FindProperty("m_LocalRotation");
                mScale = so.FindProperty("m_LocalScale");
            }
            catch { }
        }

        extensionBool = EditorPrefs.GetBool("extensionBool");

        buttonHandlerArray = new ButtonHandler[9];
        buttonHandlerArray[0] = new ButtonHandler("Position Copy", () =>
        {
            var select = Selection.activeGameObject;
            if (select == null)
                return;
            StringBuilder s = new StringBuilder();
            // x,y,z
            s.Append(mPos.vector3Value.x.ToString() + "," + mPos.vector3Value.y.ToString() + "," + mPos.vector3Value.z.ToString());
            //添加到剪贴板
            UnityEngine.GUIUtility.systemCopyBuffer = s.ToString();
        });
        buttonHandlerArray[1] = new ButtonHandler("Position Paste", () =>
        {
            //把数值打印出来
            string s = UnityEngine.GUIUtility.systemCopyBuffer;
            try
            {
                mPos.vector3Value = ParseV3(s);
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
                return;
            }
        });
        buttonHandlerArray[2] = new ButtonHandler("Position Reset", () =>
        {
            mPos.vector3Value = Vector3.zero;
        });
        buttonHandlerArray[3] = new ButtonHandler("Rotation Copy", () =>
        {
            //把数值打印出来
            var select = Selection.activeGameObject;
            if (select == null)
                return;
            StringBuilder s = new StringBuilder();
            s.Append(mRot.quaternionValue.eulerAngles.x + "," + mRot.quaternionValue.eulerAngles.y + "," + mRot.quaternionValue.eulerAngles.z);
            //添加到剪贴板
            UnityEngine.GUIUtility.systemCopyBuffer = s.ToString();
        });
        buttonHandlerArray[4] = new ButtonHandler("Rotation Paste", () =>
        {
            //把数值打印出来
            Debug.Log(UnityEngine.GUIUtility.systemCopyBuffer);
            string s = UnityEngine.GUIUtility.systemCopyBuffer;
            try
            {
                mRot.quaternionValue = Quaternion.Euler(ParseV3(s));
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
                return;
            }
        });
        buttonHandlerArray[5] = new ButtonHandler("Rotation Reset", () =>
        {
            mRot.quaternionValue = Quaternion.identity;
        });
        buttonHandlerArray[6] = new ButtonHandler("Scale Copy", () =>
        {
            //把数值打印出来
            var select = Selection.activeGameObject;
            if (select == null)
                return;
            StringBuilder s = new StringBuilder();
            s.Append(mScale.vector3Value.x.ToString() + "," + mScale.vector3Value.y.ToString() + "," + mScale.vector3Value.z.ToString());
            //添加到剪贴板
            UnityEngine.GUIUtility.systemCopyBuffer = s.ToString();
        });
        buttonHandlerArray[7] = new ButtonHandler("Scale Paste", () =>
        {
            //把数值打印出来
            Debug.Log(UnityEngine.GUIUtility.systemCopyBuffer);
            string s = UnityEngine.GUIUtility.systemCopyBuffer;
            try
            {
                mScale.vector3Value = ParseV3(s);
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
                return;
            }
        });
        buttonHandlerArray[8] = new ButtonHandler("Scale Reset", () =>
        {
            mScale.vector3Value = Vector3.one;
        });
    }

    private void OnDisable()
    {
        EditorPrefs.SetBool("extensionBool", extensionBool);
    }

    public override void OnInspectorGUI()
    {
        instance.OnInspectorGUI();

        GUI.color = Color.cyan;
        extensionBool = EditorGUILayout.Foldout(extensionBool, "拓展功能");
        if (extensionBool)
        {
            EditorGUILayout.BeginHorizontal();
            for (int i = 0; i < buttonHandlerArray.Length; i++)
            {
                ButtonHandler temporaryButtonHandler = buttonHandlerArray[i];
                if (GUILayout.Button(temporaryButtonHandler.showDescription, "toolbarbutton"))//, GUILayout.MaxWidth(150)
                {
                    temporaryButtonHandler.onClickCallBack();
                }
                GUILayout.Space(5);
                if ((i + 1) % 3 == 0 || i + 1 == buttonHandlerArray.Length)
                {
                    EditorGUILayout.EndHorizontal();
                    if (i + 1 < buttonHandlerArray.Length)
                    {
                        GUILayout.Space(5);
                        EditorGUILayout.BeginHorizontal();
                    }
                }
            }
        }
        GUI.color = Color.white;

        serializedObject.ApplyModifiedProperties();
    }

    Vector3 ParseV3(string strVector3)
    {
        string[] s = strVector3.Split(',');
        return new Vector3(float.Parse(s[0]), float.Parse(s[1]), float.Parse(s[2]));
    }
}

演示:

这样就实现了单独的位置/旋转/缩放复制/粘贴功能。

接下来,就实现单独的位置/旋转/缩放复制/粘贴功能以及位置/旋转/缩放一起复制和粘贴功能。

以及,自定义文本拼接的功能。

2-3、自定义文本拼接的功能

效果图:

参考代码:

csharp 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
using static UnityEditor.IMGUI.Controls.PrimitiveBoundsHandle;
using static UnityEngine.GraphicsBuffer;
using static UnityEngine.UI.Image;

[CanEditMultipleObjects]
[CustomEditor(typeof(Transform))]
public class TransformEditor : Editor
{
    static public Editor instance;
    Transform m_Transform;

    private bool extensionBool;

    string axisName = "Local";
    bool isAxis = false;
    bool isDefined = false;
    string row1;
    string row2;
    string row3;
    string row4;
    //当前的本地坐标
    SerializedProperty mPos;
    //当前的本地旋转
    SerializedProperty mRot;
    //当前的本地缩放
    SerializedProperty mScale;

    private void OnEnable()
    {
        instance = this;

        var editorType = Assembly.GetAssembly(typeof(Editor)).GetTypes().FirstOrDefault(m => m.Name == "TransformInspector");
        instance = CreateEditor(targets, editorType);

        isAxis = EditorPrefs.GetBool("isAxis");
        isDefined = EditorPrefs.GetBool("isDefined");

        m_Transform = this.target as Transform;

        if (this)
        {
            try
            {
                var so = serializedObject;
                mPos = so.FindProperty("m_LocalPosition");
                mRot = so.FindProperty("m_LocalRotation");
                mScale = so.FindProperty("m_LocalScale");
            }
            catch { }
        }
    }

    private void OnDisable()
    {
        EditorPrefs.SetBool("extensionBool", extensionBool);
        EditorPrefs.SetBool("isDefined", isDefined);
    }

    public override void OnInspectorGUI()
    {
        instance.OnInspectorGUI();

        extensionBool = EditorPrefs.GetBool("extensionBool");
        extensionBool = EditorGUILayout.Foldout(extensionBool, "拓展功能");

        if (extensionBool)
        {
            OnTopGUI();

            OnTransformGUI();

            OnPositionGUI();

            OnRotationGUI();

            OnScaleGUI();

            OnDefindGUI();
        }
    }

    void OnTopGUI()
    {
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Name");

        if (GUILayout.Button("Local/Global"))
        {
            isAxis = !isAxis;
            EditorPrefs.SetBool("isAxis", isAxis);
        }
        axisName = isAxis ? "Local" : "Global";
        GUILayout.Label("当前坐标轴:" + axisName);
        EditorGUILayout.EndHorizontal();
    }

    void OnTransformGUI()
    {
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Transform");
        if (GUILayout.Button("Copy"))
        {
            var select = Selection.activeGameObject;
            if (select == null)
                return;
            StringBuilder s = new StringBuilder();
            s.Append("Transform_");
            if (isAxis)
            {
                s.Append(FormatVe3(m_Transform.localPosition) + "_");
                s.Append(FormatVe3(m_Transform.localRotation.eulerAngles) + "_");
                s.Append(FormatVe3(m_Transform.localScale));
            }
            else
            {
                s.Append(FormatVe3(m_Transform.position) + "_");
                s.Append(FormatVe3(m_Transform.rotation.eulerAngles) + "_");
                s.Append(FormatVe3(m_Transform.localScale));
            }
            UnityEngine.GUIUtility.systemCopyBuffer = s.ToString();
        }
        if (GUILayout.Button("Paste"))
        {
            if (isDefined)
            {
                Debug.LogError("不支持自定义文本!");
                UnityEngine.GUIUtility.systemCopyBuffer = "";
                return;
            }
            string s = UnityEngine.GUIUtility.systemCopyBuffer;
            string[] sArr = s.Split('_');
            if (sArr[0] != "Transform" || s == "")
            {
                Debug.LogError("未复制Transform组件内容!");
                return;
            }
            try
            {
                m_Transform.position = ParseV3(sArr[1]);
                m_Transform.rotation = Quaternion.Euler(ParseV3(sArr[2]));
                m_Transform.localScale = ParseV3(sArr[3]);
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
                return;
            }
        }
        if (GUILayout.Button("Reset"))
        {
            m_Transform.position = Vector3.zero;
            m_Transform.rotation = Quaternion.identity;
            m_Transform.localScale = Vector3.one;
        }
        EditorGUILayout.EndHorizontal();
    }

    void OnPositionGUI()
    {
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Position");
        if (GUILayout.Button("Copy"))
        {
            var select = Selection.activeGameObject;
            if (select == null)
                return;
            StringBuilder s = new StringBuilder();
            if (isAxis)
            {
                s.Append(FormatVe3(m_Transform.localPosition));
            }
            else
            {
                s.Append(FormatVe3(m_Transform.position));
            }
            UnityEngine.GUIUtility.systemCopyBuffer = s.ToString();
            Debug.Log(s);
        }
        if (GUILayout.Button("Paste"))
        {
            if (isDefined)
            {
                Debug.LogError("不支持自定义文本!");
                UnityEngine.GUIUtility.systemCopyBuffer = "";
                return;
            }
            string s = UnityEngine.GUIUtility.systemCopyBuffer;
            if (s == "")
            {
                Debug.LogError("未复制Position内容!");
                return;
            }
            try
            {
                m_Transform.position = ParseV3(s);
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
                return;
            }
        }
        if (GUILayout.Button("Reset"))
        {
            m_Transform.position = Vector3.zero;
        }
        EditorGUILayout.EndHorizontal();
    }

    void OnRotationGUI()
    {
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Rotation");
        if (GUILayout.Button("Copy"))
        {
            var select = Selection.activeGameObject;
            if (select == null)
                return;
            StringBuilder s = new StringBuilder();
            if (isAxis)
            {
                s.Append(FormatVe3(m_Transform.localRotation.eulerAngles));
            }
            else
            {
                s.Append(FormatVe3(m_Transform.rotation.eulerAngles));
            }
            UnityEngine.GUIUtility.systemCopyBuffer = s.ToString();
        }
        if (GUILayout.Button("Paste"))
        {
            if (isDefined)
            {
                Debug.LogError("不支持自定义文本!");
                UnityEngine.GUIUtility.systemCopyBuffer = "";
                return;
            }
            string s = UnityEngine.GUIUtility.systemCopyBuffer;
            if (s == "")
            {
                Debug.LogError("未复制Rotation内容!");
                return;
            }
            try
            {
                m_Transform.rotation = Quaternion.Euler(ParseV3(s));
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
                return;
            }
        }
        if (GUILayout.Button("Reset"))
        {
            m_Transform.rotation = Quaternion.identity;
        }
        EditorGUILayout.EndHorizontal();
    }

    void OnScaleGUI()
    {
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Scale");
        if (GUILayout.Button("Copy"))
        {
            var select = Selection.activeGameObject;
            if (select == null)
                return;
            StringBuilder s = new StringBuilder();
            s.Append(FormatVe3(m_Transform.localScale));
            UnityEngine.GUIUtility.systemCopyBuffer = s.ToString();
        }
        if (GUILayout.Button("Paste"))
        {
            if (isDefined)
            {
                Debug.LogError("不支持自定义文本!");
                UnityEngine.GUIUtility.systemCopyBuffer = "";
                return;
            }
            string s = UnityEngine.GUIUtility.systemCopyBuffer;
            if (s == "")
            {
                Debug.LogError("未复制Scale内容!");
                return;
            }
            try
            {
                m_Transform.localScale = ParseV3(s);
            }
            catch (System.Exception ex)
            {
                Debug.LogError(ex);
                return;
            }
        }
        if (GUILayout.Button("Reset"))
        {
            m_Transform.localScale = Vector3.one;
        }
        EditorGUILayout.EndHorizontal();
    }

    void OnDefindGUI()
    {
        GUILayout.BeginVertical();
        isDefined = GUILayout.Toggle(isDefined, "启用自定义文本拼接");
        if (isDefined)
        {
            GUILayout.BeginHorizontal();
            row1 = GUILayout.TextField(row1);
            GUILayout.Label("X");
            row2 = GUILayout.TextField(row2);
            GUILayout.Label("Y");
            row3 = GUILayout.TextField(row3);
            GUILayout.Label("Z");
            row4 = GUILayout.TextField(row4);
            GUILayout.EndHorizontal();
        }
        GUILayout.EndVertical();
    }

    // x,y,z
    Vector3 ParseV3(string strVector3)
    {
        string[] s = strVector3.Split(',');
        return new Vector3(float.Parse(s[0]), float.Parse(s[1]), float.Parse(s[2]));
    }

    // x,y,z
    string FormatVe3(Vector3 ve3)
    {
        string str;
        if (!isDefined)
        {
            str = ve3.x + "," + ve3.y + "," + ve3.z;
        }
        else
        {
            str = row1 + ve3.x + row2 + ve3.y + row3 + ve3.z + row4;
        }
        return str;
    }
}

三、后记

如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。


你的点赞就是对博主的支持,有问题记得留言:

博主主页有联系方式。

博主还有跟多宝藏文章等待你的发掘哦:

专栏 方向 简介
Unity3D开发小游戏 小游戏开发教程 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。
Unity3D从入门到进阶 入门 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。
Unity3D之UGUI UGUI Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。
Unity3D之读取数据 文件读取 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。
Unity3D之数据集合 数据集合 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。
Unity3D之VR/AR(虚拟仿真)开发 虚拟仿真 总结博主工作常见的虚拟仿真需求进行案例讲解。
Unity3D之插件 插件 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等
Unity3D之日常开发 日常记录 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
Unity3D之日常BUG 日常记录 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。
相关推荐
hccee9 分钟前
C# IO文件操作
开发语言·c#
hummhumm14 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊24 分钟前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
zmd-zk38 分钟前
flink学习(2)——wordcount案例
大数据·开发语言·学习·flink
好奇的菜鸟43 分钟前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
Alive~o.01 小时前
Go语言进阶&依赖管理
开发语言·后端·golang
花海少爷1 小时前
第十章 JavaScript的应用课后习题
开发语言·javascript·ecmascript
手握风云-1 小时前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
喵叔哟1 小时前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构
尘浮生1 小时前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea