[Développement de l'éditeur Unity3D] Implémentez l'extension du composant Transform dans Unity3D, copiez, collez et restaurez rapidement [très pratique]

Lecture recommandée

Bonjour à tous, je suis un ingénieur bouddhiste ☆The Quiet Little Magic Dragon☆ . Je mets à jour les compétences de développement d'Unity de temps en temps. Si vous le trouvez utile, n'oubliez pas de cliquer trois fois.

Introduction

Au cours du développement, nous rencontrons souvent des opérations fréquentes de copier-coller des coordonnées, de rotation et de mise à l'échelle des objets.

Il est difficile de copier et coller à l'aide des propres composants d'Unity :
Copier :
Insérer la description de l'image ici
 Coller :
Insérer la description de l'image ici
Il y a également certaines valeurs qui doivent être copiées dans le code, telles que la position, la rotation et la mise à l'échelle. Il est très difficile de copier et de coller collez-les un par un, et certains doivent être copiés et ajoutés au texte personnalisé. Également très gênant.

Par conséquent, un petit outil a été développé pour améliorer l’efficacité du développement.

2. Texte

2-1. Réalisez des fonctions rapides de copier/coller, de position/rotation/zoom

Rendu :
Insérer la description de l'image ici
créez un nouveau script dans le dossier Editeur, nommez-le comme vous le souhaitez, puis modifiez le code :

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
}

Résultats d'exécution :
Insérer la description de l'image ici
Ceci permet d'obtenir des fonctions de base rapides de copier/coller, de position/rotation/zoom.

Ensuite, implémentons un copier-coller séparé de la position, de la rotation et de l'échelle.

2-2. Fonctions séparées d'affectation et de collage de position, de rotation et de mise à l'échelle

Rendu :
Insérer la description de l'image ici
exemple de code :

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

Démo :
Insérer la description de l'image ici
cela implémente une fonctionnalité séparée de copier/coller de position/rotation/échelle.

Ensuite, implémentez ensemble la fonction de copier/coller de position/rotation/échelle séparée et la fonction de copier/coller de position/rotation/échelle.

Et la fonction de personnalisation de l’épissage du texte.

2-3. Fonction d'épissage de texte personnalisée

Le rendu:
Insérer la description de l'image ici

Code de référence:

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. Post-scriptum

Si vous trouvez cet article utile, n'oubliez pas de cliquer sur « Suivre » pour éviter de vous perdre et continuer à partager des articles plus utiles sur Unity.


Vos likes sont un soutien pour le blogueur. Si vous avez des questions, veuillez laisser un message :

La page d’accueil du blogueur contient des informations de contact.

Le blogueur propose également de nombreux articles trésors à découvrir :

Colonne direction Introduction
Unity3D développe des petits jeux Tutoriel de développement de mini-jeux Partagez quelques petits jeux développés à l'aide du moteur Unity3D et partagez quelques tutoriels sur la création de petits jeux.
Unity3D de l'entrée à l'avancée commencer Inspirez-vous de l'auto-apprentissage d'Unity, résumez le parcours d'apprentissage d'Unity à partir de zéro et maîtrisez C# et Unity.
Interface utilisateur utilisateur Unity3D UGU Une analyse complète du système d'interface utilisateur UGUI de Unity, en commençant par les contrôles de base de UGUI, puis en enseignant de manière exhaustive les principes et l'utilisation de UGUI.
Lecture de données dans Unity3D lecture de fichiers Utilisez Unity3D pour lire des documents txt, des documents json, des documents XML, des documents CSV et des documents Excel.
Collecte de données Unity3D collecte de données Collection de tableaux : partage de connaissances sur les collections de données telles que les tableaux, les listes, les dictionnaires, les piles et les listes chaînées.
Développement Unity3D VR/AR (simulation virtuelle) réalité virtuelle Résumez les besoins courants des blogueurs en matière de simulation virtuelle et expliquez-les avec des cas.
Plug-in Unity3D brancher Partagez principalement certaines méthodes d'utilisation des plug-ins utilisées dans le développement Unity, l'introduction des plug-ins, etc.
Développement quotidien de Unity3D enregistrements quotidiens Principalement utilisé par les blogueurs dans le développement quotidien, y compris les méthodes et techniques, les idées de développement, le partage de code, etc.
BUG quotidien d'Unity3D enregistrements quotidiens Enregistrez les bugs et pièges rencontrés lors du développement du projet à l'aide de l'éditeur Unity3D afin que les générations futures puissent s'y référer.

Je suppose que tu aimes

Origine blog.csdn.net/q764424567/article/details/133859784
conseillé
Classement