zoukankan      html  css  js  c++  java
  • Unity Editor开发中查找属性的两种写法对比

    从2017开始,在editor脚本中查找属性是这样写的 var m_Script = serializedObject.FindProperty("m_Script");

    SerializedProperty

    以UGUI的源码为例

    using UnityEngine;
    using UnityEngine.UI;
    using UnityEditor.AnimatedValues;
    
    namespace UnityEditor.UI
    {
        [CustomEditor(typeof(Selectable), true)]
        /// <summary>
        ///   Custom Editor for the Selectable Component.
        ///   Extend this class to write a custom editor for an Selectable-derived component.
        /// </summary>
        public class SelectableEditor : Editor
        {
            protected virtual void OnEnable()
            {
                SerializedProperty m_Script = serializedObject.FindProperty("m_Script");
                SerializedProperty m_InteractableProperty = serializedObject.FindProperty("m_Interactable");
    		}
    	}
    }
    

    直接修改

    而我在unity4.x时,查找某个属性是这样写的,我在Unity2019和Unity2020中测试目前这种写法还是生效的

    using UnityEditor;
    using UnityEngine;
     
    [CustomEditor(typeof(MyActor))]
    public class MyActorInspector : Editor
    {
        public int ATKProp;
     
        void OnEnable()
        {
            MyActor myActor = target as MyActor; //类型转换为MyActor
            ATKProp = myActor.ATK;//缓存对象的某个字段和属性
        }
     
        public override void OnInspectorGUI()
        {
            ATKProp = EditorGUILayout.IntSlider("ATK", ATKProp, 0, 100);
        }
    }
    

    这两种写法有什么区别呢?

    serializedObject.FindProperty可以修改private的值,而直接修改只能访问public的值

    SerializedProperty被编辑的对象需要加上[Serializable]标签,且要找的属性如果是private需要加上[SerializeField]标签,否则序列化会报错

    SerializedProperty写法的值在编辑过程中可以撤消(Undo)、Prefab overrides,而直接修改无法撤消,就是按Ctrl+Z无效,所以建议平时还是使用FindProperty开发。

    SerializedProperty中指向当前对象叫 serializedObject ,在直接写叫 target

    SerializedProperty文档:https://docs.unity.cn/cn/current/ScriptReference/SerializedObject.html

    在官网文档中也有提到这两种写法的区别:https://docs.unity.cn/cn/current/ScriptReference/Editor.html

    SerializedProperty文档

    // 更新序列化属性,写在OnInspectorGUI的开头
    serializedObject.Update ();
    
    //对序列化属性修改后,需要应用修改才能保存序列化数据,要写在OnInspectorGUI方法的结尾
    serializedObject.ApplyModifiedProperties ();
    

    遇到问题

    serializedObject复选框无法勾选

    比如下面这段代码就会让复选框无法操作

    protected override void OnEnable()
    {
    	base.OnEnable();
    	UseLangId = serializedObject.FindProperty("useLangId");
    }
    
    public override void OnInspectorGUI()
    {
    	EditorGUILayout.PropertyField(UseLangId,"使用语言包"); //这样会导致Inspector的复选框,无法勾选和取消
        serializedObject.Update();//NOTE 这句要放在最前面,否则无法操作复选框
        serializedObject.ApplyModifiedProperties();
    	base.OnInspectorGUI();
    }
    

    EditorGUI.indentLevel是什么意思?

    增加缩进深度,就是在这个属性的开头会有空格,需要配套出现,示例如下:

    ++EditorGUI.indentLevel;
    for (int i = 0; i < paramArr.arraySize; i++)
    {
    	paramArr.GetArrayElementAtIndex(i).stringValue = EditorGUILayout.TextField(paramArr.GetArrayElementAtIndex(i).stringValue);
    	args[i] = paramArr.GetArrayElementAtIndex(i).stringValue;
    }
    --EditorGUI.indentLevel;
    
  • 相关阅读:
    LeetCode449. 序列化和反序列化二叉搜索树
    LeetCode448. 找到所有数组中消失的数字
    一行代码如何隐藏 Linux 进程?
    C语言这么厉害,它自身又是用什么语言写的?
    了解C语言,是否代表了解C ++的一半?
    C语言小白那些不知道的事儿
    6 条 Git 实用技巧
    干货来袭,收藏方便找到该网站
    零基础小白如何入门Shell,快来看看(收藏)这篇大总结!!
    Java用于嵌入式系统的优点和局限
  • 原文地址:https://www.cnblogs.com/zhaoqingqing/p/14825879.html
Copyright © 2011-2022 走看看