unity Editor编辑器 自定义

unity Editor编辑器 自定义


知名插件:
Runtime Editor 添加链接描述
Odin - Inspector and Serializer
有大佬可以留言分享下学习经验。本人只根据官方的进行了总结。之后有内容也会补充!

menu排序Id
EditorWindow

Menu相关部分

以下为本人总结的Menu相关部分,包括:标题栏、windows、GameObject、Assets目录右键、菜单的分层、脚本右键、获取选中的物体、快捷键。

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class Tools
{
     //添加标题
     /*
     [MenuItem("Tools/test")]
     public static void Test()
     {
          Debug.Log("abc");
     }
     [MenuItem("Tools/test1")]
     public static void Test2()
     {
          Debug.Log("abc1");
     }
     [MenuItem("Tools/test2")]
     public static void Test3()
     {
          Debug.Log("abc2");
     }
     //子级
     [MenuItem("Tools/test2/test")]
     public static void Test4()
     {
          Debug.Log("test2/test");
     }*/
     //window下
     [MenuItem("Window/WinTest")]
     public static void WinTest()
     {
          Debug.Log("Winabc2");
     }
     //GameObject下 ,可以在Hierachy右键显示
     [MenuItem("GameObject/Testobj",false,11)]
     public static void HierachyTest()
     {
          Debug.Log("Hierachyabc");
     }
     
     [MenuItem("GameObject/Testobj",true,11)]
     public static bool HierachyTest1()
     {
          return Selection.count > 0;
     }
     //分层
     /*[MenuItem("Tools/test",false,1)]
     public static void Test()
     {
          Debug.Log("abc");
     }
     [MenuItem("Tools/test1",false,0)]
     public static void Test2()
     {
          Debug.Log("abc1");
     }
     [MenuItem("Tools/test2",false,12)]
     public static void Test3()
     {
          Debug.Log("abc2");
     }*/
     //Assets目录右键
     [MenuItem("Assets/Test",false,11)]
     public static void AssetsTest()
     {
          Debug.Log("Assetsabc");
     }
     //脚本右键
     [MenuItem("CONTEXT/TestSpcrite/rs",false,5)]
     public static void InspectorTest()
     {
          Debug.Log("Assetsabc");
     }
     [MenuItem("CONTEXT/Rigidbody/test")]
     public static void InspectorTestSetValue(MenuCommand command)
     {
          var rig = command.context as Rigidbody;
          Debug.Log($"rig_mass{rig.mass},rig_Gravity{rig.useGravity}");
          rig.mass = 5;
          rig.useGravity = false;
          Debug.Log($"rig_mass{rig.mass},rig_Gravity{rig.useGravity}");
     }
     //选择物体
     [MenuItem("Test/Select",false,5)]
     public static void InspectorSelect()
     {
          Debug.Log("Count"+Selection.count);
          Debug.Log("ObjectsLength"+Selection.objects.Length);
     }
     //可撤销删除 快捷键 % (ctrl on Windows, cmd on macOS), # (shift), & (alt)
     [MenuItem("Test/Delete %DEL",false,6)]
     public static void InspectorDelete()
     {
          foreach (var obj in Selection.objects)
          {
               Undo.DestroyObjectImmediate(obj);     
          }
          Debug.Log("删除选中的物体,并可以撤销");
     }

     //第二个参数,方法是否启用, "Test/Select"名字相同,有bool 返回值,true状态;先判断true方法,在判断false
     //选择物体
     [MenuItem("Test/Select",true)]
     public static bool InspectorCanSelect()
     {
          return Selection.count > 0;
     }
     

     

}

windows弹窗

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class EditorWindowExample : EditorWindow
{
    [MenuItem("Window/Show")]
    public static void ShowWin()
    {
        var win = GetWindow<EditorWindowExample>();
        win.Show();
    }

    public string str = "";

#region Dropdown

#region EnumMaskField

    public enum Example
    {
        Option_One   = 1, //bits: 0000 0001
        Option_Two   = 2, //bits: 0000 0010
        Option_Three = 3  //bits: 0000 0100
    }

    Example staticFlagMask = 0;

#endregion

#region EnumPopup

    public enum OPTIONS
    {
        CUBE   = 0,
        SPHERE = 1,
        PLANE  = 2
    }

    public OPTIONS op;

#endregion

#region IntPopup

    int      selectedSize = 1;
    string[] names        = new string[] { "Normal", "Double", "Quadruple" };
    int[]    sizes        = new int[] { 1, 2, 4 };

#endregion

#region Popup

    public string[] options = new string[] { "Cube", "Sphere", "Plane" };
    public int      index   = 0;

#endregion

#region EnumMaskPopup

    public enum Options
    {
        CUBE   = 0,
        SPHERE = 1,
        PLANE  = 2
    }

    public Options m_options;

#endregion

#endregion

    private GameObject m_objectValue;

    private int m_intValue; //定义修改内容;
    
    private string    m_textValue;
    private float     m_floatValue;
    private Vector2   m_vec2;
    private Vector3   m_vec3;
    private Vector4   m_vec4;
    private Bounds    m_bounds;
    private BoundsInt m_boundsInt;

    private int    m_layer;
    private string m_tag;
    
    private Color      m_color;
    private GUIContent colorTitle = new GUIContent("颜色选择");
    
    private AnimationCurve m_curve = AnimationCurve.Linear(0, 0, 1, 1);
    private void OnGUI()
    {
        GUILayout.Label("输入");
        str = GUILayout.TextField(str);
        if (GUILayout.Button("创建"))
        {
            var gameObject = new GameObject(str);
            Undo.RegisterCreatedObjectUndo(gameObject, "obj");
        }

    #region Dropdown

        var        dropdownText = "Dropdown";
        GUIContent content      = new GUIContent(dropdownText); //定义一下显示内容

        if (EditorGUILayout.DropdownButton(content, FocusType.Passive))
        {
            var         options = new string[] { "A", "B", "C", "D" };
            GenericMenu menu    = new GenericMenu();
            for (int i = 0; i < options.Length; i++)
            {
                var a = i;
                //bool,即菜单中项目旁边的勾号;每个选项默认是否选中
                //func,点击之后的方法
                /*menu.AddItem(new GUIContent(options[i]), false, () =>
                {
                    Debug.Log($"选中下拉列表{options[a]}");
                });*/
                menu.AddItem(new GUIContent(options[i]), dropdownText.Equals(options[i]),
                    () => { Debug.Log($"选中下拉列表{options[a]}"); });
                menu.ShowAsContext(); //显示菜单
            }

            Debug.Log("据说是按下就触发,而不是抬起");
        }

    #region EnumMaskField

        //可以多选
        staticFlagMask = (Example)EditorGUILayout.EnumFlagsField("EnumFlagsField:", staticFlagMask);

    #endregion


    #region EnumPopup

        op = (OPTIONS)EditorGUILayout.EnumPopup("EnumPopup:", op);

    #endregion

    #region IntPopup

        selectedSize = EditorGUILayout.IntPopup("IntPopup: ", selectedSize, names, sizes);

    #endregion

    #region Popup

        index = EditorGUILayout.Popup("Popup:", index, options);

    #endregion

    #region EnumMaskPopup

        m_options = (Options)EditorGUILayout.EnumFlagsField("EnumFlagsField:", m_options);

    #endregion

    #endregion


    #region 对象域

        m_objectValue = EditorGUILayout.ObjectField(m_objectValue, typeof(GameObject), true) as GameObject;

    #endregion


    #region 整数域

        m_intValue = EditorGUILayout.IntField("整型输入框", m_intValue); //Title + Value

    #endregion

    #region 浮点、字符串、向量等各种域

        m_floatValue = EditorGUILayout.FloatField("Float 输入:", m_floatValue);
        m_textValue  = EditorGUILayout.TextField("Text输入:", m_textValue);
        m_vec2       = EditorGUILayout.Vector2Field("Vec2输入: ", m_vec2);
        m_vec3       = EditorGUILayout.Vector3Field("Vec3输入: ", m_vec3);
        m_vec4       = EditorGUILayout.Vector4Field("Vec4输入: ", m_vec4);
        m_bounds     = EditorGUILayout.BoundsField("Bounds输入: ", m_bounds);
        m_boundsInt  = EditorGUILayout.BoundsIntField("Bounds输入: ", m_boundsInt);

    #endregion

    #region 标签/层级选择域

        m_layer = EditorGUILayout.LayerField("层级选择", m_layer);
        m_tag   = EditorGUILayout.TagField("标签选择", m_tag);

    #endregion

    #region 颜色域

        m_color = EditorGUILayout.ColorField(colorTitle, m_color, true, true, true);

    #endregion

    #region 动画曲线域

        m_curve = EditorGUILayout.CurveField("动画曲线:", m_curve);

    #endregion
    }
}

Inspector

与下面的InspectorRightExample基类脚本对应。可以给脚本添加按钮等GUI方法。

using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(InspectorRightExample))]   
public class EditorInspectorExample : Editor
{
    private InspectorRightExample _inspectorRightExample;
    private void OnEnable()
    {
        _inspectorRightExample = target as InspectorRightExample;
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        GUILayout.Label("Inspector Right Example");
        GUILayout.Space(10);
        if (GUILayout.Button("这是一个按钮")) //自定义按钮
        {
            Debug.Log("Hello world");
        }
    }
}


脚本

除此脚本外,其余放在editor目录下面。

using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(InspectorRightExample))]   
public class EditorInspectorExample : Editor
{
    private InspectorRightExample _inspectorRightExample;
    private void OnEnable()
    {
        _inspectorRightExample = target as InspectorRightExample;
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        GUILayout.Label("Inspector Right Example");
        GUILayout.Space(10);
        if (GUILayout.Button("这是一个按钮")) //自定义按钮
        {
            Debug.Log("Hello world");
        }
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Unity编辑器中显示自定义结构体,需要使用Unity的PropertyDrawer功能。您可以通过创建一个继承自PropertyDrawer的类并使用CustomPropertyDrawer特性来实现。 您可以在代码中这样实现: ``` using UnityEngine; using UnityEditor; [CustomPropertyDrawer(typeof(YourCustomStruct))] public class YourCustomStructDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // Your custom GUI code here } } ``` 这样,在Unity编辑器中,您就可以看到您自定义的结构体以符合您的需求的方式显示了。 ### 回答2: 在Unity编辑器中显示自定义struct可以通过创建自定义Editor类来实现。以下是一个基本的示例: 首先,我们需要创建一个名为"CustomStruct"的自定义struct,包含我们希望显示的成员变量和方法。 ```csharp [System.Serializable] public struct CustomStruct { public int intValue; public float floatValue; public string stringValue; public void CustomMethod() { // 自定义方法的实现 } } ``` 然后,我们创建一个名为"CustomStructEditor"的自定义Editor类,并继承自UnityEditor类库中的Editor类。 ```csharp using UnityEditor; using UnityEngine; [CustomEditor(typeof(MonoBehaviour))] public class CustomStructEditor : Editor { private SerializedProperty intValueProp; private SerializedProperty floatValueProp; private SerializedProperty stringValueProp; private void OnEnable() { intValueProp = serializedObject.FindProperty("intValue"); floatValueProp = serializedObject.FindProperty("floatValue"); stringValueProp = serializedObject.FindProperty("stringValue"); } public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(intValueProp); EditorGUILayout.PropertyField(floatValueProp); EditorGUILayout.PropertyField(stringValueProp); serializedObject.ApplyModifiedProperties(); } } ``` 最后,将该自定义Editor类与含有自定义struct的MonoBehaviour脚本关联起来。例如,我们可以将CustomStructEditor类与一个名为"CustomBehaviour"的脚本关联: ```csharp [CustomEditor(typeof(CustomBehaviour))] public class CustomBehaviourEditor : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); CustomBehaviour customBehaviour = (CustomBehaviour)target; EditorGUILayout.Space(); if (GUILayout.Button("Call Custom Method")) { customBehaviour.customStruct.CustomMethod(); } } } ``` 这样,在Unity编辑器中,我们可以像显示其他属性一样显示我们自定义的struct,同时还可以调用自定义方法。 希望这个简单的示例可以帮到您。 ### 回答3: 在Unity编辑器中显示自定义的struct(结构体)数据类型,需要通过自定义Unity的自定义编辑器(Custom Editor)来实现。 首先,我们需要在Unity项目中创建一个C#脚本,并在脚本中定义我们需要显示的struct数据类型。例如,我们可以创建一个名为"CustomStruct.cs"的脚本,在其中定义了一个名为"CustomStruct"的struct数据类型。 接下来,我们可以创建一个名为"CustomStructEditor.cs"的自定义编辑器脚本。在该脚本中,我们可以使用Unity的GUI系统来自定义显示struct数据类型的方式。我们可以使用GUILayout或者EditorGUILayout等GUI布局函数来创建自定义的Inspector面板。 在CustomStructEditor.cs中,我们可以重写OnInspectorGUI函数,并在该函数中编写我们希望在Inspector面板中显示的内容。我们可以使用SerializedProperty来访问和修改struct中的成员变量。 例如,我们可以使用GUILayout.Label函数来显示一些文本,使用SerializedProperty.FindPropertyRelative函数来获取struct中的成员变量,并使用 EditorGUILayout.PropertyField 函数来显示每个成员变量。 最后,在CustomStruct.cs脚本的声明前面添加"[CustomEditor(typeof(CustomStructEditor))]"来告诉Unity,我们希望使用我们自定义编辑器来显示CustomStruct。 总结,通过使用自定义编辑器,我们可以在Unity编辑器中显示自定义的struct数据类型。自定义编辑器使我们能够按照我们的需求来显示和修改struct的成员变量,使开发工作更加高效和灵活。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值