美文网首页
Odin Inspector 系列教程 --- 自定义 Valu

Odin Inspector 系列教程 --- 自定义 Valu

作者: su9257_海澜 | 来源:发表于2019-10-30 11:38 被阅读0次

    本次讲解的是对应我们自己编写的类或者结构体,按照需求自定义Drawer的简单示例

    Value Drawer是Odin最基本的Drawer型,通常是最终在检查员中完成属性最终绘制的绘制。因此,它们通常位于绘制链中的最后一个抽屉中,通常不会延续该链。所以本示例不会出现this.CallNextDrawer(label);等字样。

    示例比较简单,我们接下来分几个步骤即可完成

    创建我们的自定义类
        // 演示如何为自定义类型生成自定义drawer的示例。
        [TypeInfoBox("此示例演示如何为自定义结构或类实现自定义drawer")]
        public class CustomDrawerExample : MonoBehaviour
        {
            public MyStruct MyStruct;
            [ShowInInspector]
            public static float labelWidth = 10;
        }
    
        // 自定义数据结构,用于演示。
        [Serializable]
        public struct MyStruct
        {
            public float X;
            public float Y;
        }
    
    创建一个用于绘制MyStruct的Darwe类

    此绘制类需要继承OdinValueDrawer,并传入对应的类型

        public class CustomStructDrawer : OdinValueDrawer<MyStruct>
        {
    
        }
    
    开始绘制

    准备工作完成,接下来开始真正的绘制,这里我们需要重写DrawPropertyLayout方法

            protected override void DrawPropertyLayout(GUIContent label)
            {
                
            }
    
    绘制主要分为以下几个步骤
    • 获取我们绘制类的值
    • 获取要绘制的区域(rect)
    • 保存原始labelWidth的宽度
    • 设定新的label宽度
    • 根据slider对应的值进行赋值
    • 恢复设定原始label宽度
    • 将新的Struct赋值给我们定义的MyStruct
            protected override void DrawPropertyLayout(GUIContent label)
            {
                //获取我们绘制类的值
                MyStruct value = this.ValueEntry.SmartValue;
    
                //获取要绘制的区域(rect)
                var rect = EditorGUILayout.GetControlRect();
                //在Odin中,标签是可选项,可以为空,所以我们必须考虑到这一点。
                if (label != null)
                {
                    rect = EditorGUI.PrefixLabel(rect, label);
                }
    
                //保存原始labelWidth的宽度,此label为struct中对应的X,Y
                var prev = EditorGUIUtility.labelWidth;
    
                //设定新的label宽度
                EditorGUIUtility.labelWidth = CustomDrawerExample.labelWidth;
    
                //根据slider对应的值进行赋值
                value.X = EditorGUI.Slider(rect.AlignLeft(rect.width * 0.5f), "X", value.X, 0, 1);
                value.Y = EditorGUI.Slider(rect.AlignRight(rect.width * 0.5f), "Y", value.Y, 0, 1);
    
                //恢复设定原始label宽度
                EditorGUIUtility.labelWidth = prev;
    
                //将新的Struct赋值给我们定义的MyStruct
                this.ValueEntry.SmartValue = value;
            }
    

    完整示例代码

    #if UNITY_EDITOR
    namespace Sirenix.OdinInspector.Demos
    {
        using UnityEngine;
        using System;
    
    #if UNITY_EDITOR
    
        using Sirenix.OdinInspector.Editor;
        using UnityEditor;
        using Sirenix.Utilities;
    
    #endif
    
        // 演示如何为自定义类型生成自定义drawer的示例。
        [TypeInfoBox("此示例演示如何为自定义结构或类实现自定义drawer")]
        public class CustomDrawerExample : MonoBehaviour
        {
            public MyStruct MyStruct;
            [ShowInInspector]
            public static float labelWidth = 10;
        }
    
        // 自定义数据结构,用于演示。
        [Serializable]
        public struct MyStruct
        {
            public float X;
            public float Y;
        }
    
    #if UNITY_EDITOR
    
        public class CustomStructDrawer : OdinValueDrawer<MyStruct>
        {
            protected override void DrawPropertyLayout(GUIContent label)
            {
                //获取我们绘制类的值
                MyStruct value = this.ValueEntry.SmartValue;
    
                //获取要绘制的区域(rect)
                var rect = EditorGUILayout.GetControlRect();
                //在Odin中,标签是可选项,可以为空,所以我们必须考虑到这一点。
                if (label != null)
                {
                    rect = EditorGUI.PrefixLabel(rect, label);
                }
    
                //保存原始labelWidth的宽度,此label为struct中对应的X,Y
                var prev = EditorGUIUtility.labelWidth;
    
                //设定新的label宽度
                EditorGUIUtility.labelWidth = CustomDrawerExample.labelWidth;
    
                //根据slider对应的值进行赋值
                value.X = EditorGUI.Slider(rect.AlignLeft(rect.width * 0.5f), "X", value.X, 0, 1);
                value.Y = EditorGUI.Slider(rect.AlignRight(rect.width * 0.5f), "Y", value.Y, 0, 1);
    
                //恢复设定原始label宽度
                EditorGUIUtility.labelWidth = prev;
    
                //将新的Struct赋值给我们定义的MyStruct
                this.ValueEntry.SmartValue = value;
            }
        }
    #endif
    }
    #endif
    
    

    更多教程内容详见:革命性Unity 编辑器扩展工具 --- Odin Inspector 系列教程

    相关文章

      网友评论

          本文标题:Odin Inspector 系列教程 --- 自定义 Valu

          本文链接:https://www.haomeiwen.com/subject/iakovctx.html