[Desarrollo del editor Unity3D] Implemente la expansión del componente Transform en Unity3D, copie, pegue y restaure rápidamente [muy práctico]

Lectura recomendada

Hola a todos, soy un ingeniero budista ☆The Quiet Little Magic Dragon☆ . Actualizo las habilidades de desarrollo de Unity de vez en cuando. Si lo encuentra útil, recuerde hacer clic tres veces.

I. Introducción

Durante el desarrollo, a menudo nos encontramos con operaciones frecuentes de copiar y pegar coordenadas, rotación y escala de objetos.

Es problemático copiar y pegar usando los propios componentes de Unity:
Copiar:
Insertar descripción de la imagen aquí
Pegar:
Insertar descripción de la imagen aquí
También hay algunos valores que deben copiarse en el código, como posición, rotación y escala, es muy problemático copiar y Pegue uno por uno, y algunos deben copiarse y agregarse al texto personalizado, lo que también es muy inconveniente.

Por lo tanto, se desarrolló una pequeña herramienta para mejorar la eficiencia del desarrollo.

2. Texto

2-1 Realice funciones rápidas de copiar/pegar, posición/rotación/zoom

Representación:
Insertar descripción de la imagen aquí
cree un nuevo script en la carpeta Editor, asígnele el nombre que desee y luego edite el código:

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
}

Resultados de ejecución:
Insertar descripción de la imagen aquí
Esto logra funciones básicas rápidas de copiar/pegar, posición/rotación/zoom.

A continuación, implementemos copiar y pegar por separado la posición, rotación y escala.

2-2 Funciones separadas de asignación y pegado de posición, rotación y escala

Representación:
Insertar descripción de la imagen aquí
Código de muestra:

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]));
    }
}

Demostración:
Insertar descripción de la imagen aquí
esto implementa una función separada de copiar/pegar de posición/rotación/escala.

A continuación, implemente la función separada de copiar y pegar de posición/rotación/escala y la función de copiar y pegar de posición/rotación/escala juntas.

Y la función de personalizar el empalme de texto.

2-3 Función de empalme de texto personalizada

Representación:
Insertar descripción de la imagen aquí

Código de referencia:

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;
    }
}

3. Posdata

Si encuentra útil este artículo, no olvide hacer clic en "Seguir" para evitar perderse y continuar compartiendo más artículos útiles sobre Unity.


Tus me gusta son apoyo para el blogger, si tienes alguna pregunta, deja un mensaje:

La página de inicio del blogger tiene información de contacto.

El blogger también tiene muchos artículos tesoros esperando que los descubras:

Columna dirección Introducción
Unity3D desarrolla pequeños juegos Tutorial de desarrollo de minijuegos. Comparta algunos juegos pequeños desarrollados con el motor Unity3D y comparta algunos tutoriales sobre cómo crear juegos pequeños.
Unity3D desde básico hasta avanzado empezando Inspírese en el autoestudio de Unity, resuma la ruta para aprender Unity desde cero y tenga conocimientos de C # y Unity.
Unity3D UGUI UGUI Un análisis completo del sistema UI de Unity, UGUI, comenzando con los controles básicos de UGUI y luego enseñando de manera integral los principios y el uso de UGUI.
Leer datos en Unity3D lectura de archivos Utilice Unity3D para leer documentos txt, documentos json, documentos xml, documentos csv y documentos Excel.
Recopilación de datos Unity3D recopilación de datos Colección de matrices: intercambio de conocimientos sobre colecciones de datos como matrices, listas, diccionarios, pilas y listas vinculadas.
Desarrollo Unity3D VR/AR (simulación virtual) realidad virtual Resuma las necesidades comunes de simulación virtual de los blogueros y explíquelas con casos.
complemento Unity3D enchufar Comparta principalmente algunos métodos de uso de complementos utilizados en el desarrollo de Unity, introducción de complementos, etc.
Desarrollo diario de Unity3D registros diarios Utilizado principalmente por blogueros en el desarrollo diario, incluidos métodos y técnicas, ideas de desarrollo, intercambio de código, etc.
ERROR diario de Unity3D registros diarios Registre los errores y dificultades encontrados durante el desarrollo del proyecto utilizando el editor Unity3D para que las generaciones futuras puedan tener alguna referencia.

Supongo que te gusta

Origin blog.csdn.net/q764424567/article/details/133859784
Recomendado
Clasificación