zoukankan      html  css  js  c++  java
  • 自定义Inspector检视面板

    Unity中的Inspector面板可以显示的属性包括以下两类:
    (1)C#以及Unity提供的基础类型;
    (2)自定义类型,并使用[System.Serializable]关键字序列化,比如:
    [System.Serializable]
    public class TestClass
    {
        public Vector3 vec = Vector3.zero;
        public Color clr = Color.green;
    }

      也可以使用[System.NonSerialized]标记不需要显示的属性,比如:

    public class TestClass
    {
        [System.NonSerialized]
        public Vector3 vec = Vector3.zero;
    }

      有的时候对于U3D默认的Inspector不能满足需求,则可以对特定类型的Inspector面板进行自定义:编写一个对应的Editor类,然后重写其OnInspector方法,比如我们有如下类型:

    using UnityEngine;
    using System.Collections;
    
    [System.Serializable]
    public class TestClass
    {
        public Vector3 vec = Vector3.zero;
        [System.NonSerialized]
        public Color clr = Color.green;
    }
    
    [ExecuteInEditMode()]
    [RequireComponent(typeof(TestComponent))]
    public class TestInspector : MonoBehaviour 
    {
        public Vector3 lookAtPoint = Vector3.zero;
        public Vector3 pos = Vector3.zero;
        public TestClass testObj = new TestClass();
    
        void Update()
        {
            transform.LookAt(lookAtPoint);
            transform.position = pos;
        }
    }

      然后在Editor目录下添加如下脚本:

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    
    [CustomEditor(typeof(TestInspector))]
    public class TestInspectorEditor : Editor
    {
        private SerializedObject obj;
        private SerializedProperty lookAtPoint;
        private SerializedProperty pos;
        private SerializedProperty testObj;
    
        // 添加TestInspector组件的GameObject被选中时触发该函数
        void OnEnable()
        {
            obj = new SerializedObject(target);
            lookAtPoint = obj.FindProperty("lookAtPoint");
            pos = obj.FindProperty("pos");
            testObj = obj.FindProperty("testObj");
        }
    
        // 重写Inspector检视面板
        public override void OnInspectorGUI()
        {
            obj.Update();
    
            EditorGUILayout.PropertyField(lookAtPoint);
            EditorGUILayout.PropertyField(pos);
            EditorGUILayout.PropertyField(testObj, true);   // 第二个参数表示有子节点需要显示
    
            obj.ApplyModifiedProperties();
        }
    
    }

      在OnInspector函数中就可以实现你想要的效果。

       上面的代码中有几点需要注意:

      (1)[ExecuteInEditMode()]这个函数可以使代码在编辑模式下运行,不需要运行游戏;

      (2)TestInspectorEditor类必须继承自Editor,CustomEditor告诉U3D哪个组建类型需要自定义,OnInspectorGUI在显示组件的Inspector面板时调用;

      (3)SerializedObject序列化物体、SerializedProperty序列化属性和Editor这三者一起使用,用来访问和更新组件的属性,SeriailzedProperty能够以通用的方式访问所有的基础类型,包括对数组的控制等;

       (4)可以在OnInspectorGUI中调用DrawDefaultInspector函数用来显示默认的监事面板内容;

       (5)EditorGUILayout.PropertyField(testObj, true);如果该类型有子节点,第二个参数需要设置为true才能正确的展开;

       (6)[HideInInspector]也可用于隐藏属性显示。

    ******************************************************************************************

      除了自定义Inspector检视面板,我们还可以类似的方法自定义场景视图中对物体的控制,方法是重定义Editor的OnSceneGUI()函数,比如:

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    
    [CustomEditor(typeof(TestInspector))]
    public class TestInspectorEditor : Editor
    {
    
        private SerializedObject obj;
        private SerializedProperty lookAtPoint;
        private SerializedProperty pos;
        private SerializedProperty testObj;
    
        // 添加TestInspector组件的GameObject被选中时触发该函数
        void OnEnable()
        {
            obj = new SerializedObject(target);
            lookAtPoint = obj.FindProperty("lookAtPoint");
            pos = obj.FindProperty("pos");
            testObj = obj.FindProperty("testObj");
        }
    
        // 重写Inspector检视面板
        public override void OnInspectorGUI()
        {
            obj.Update();
    
            EditorGUILayout.PropertyField(lookAtPoint);
            EditorGUILayout.PropertyField(pos);
            EditorGUILayout.PropertyField(testObj, true);   // 第二个参数表示有子节点需要显示
    
            obj.ApplyModifiedProperties();
        }
    
        void OnSceneGUI()
        {
            // 绘制一条由target到世界坐标原点的直线,颜色为黄色
            Handles.color = Color.yellow;
            Handles.DrawLine((target as TestInspector).transform.position, Vector3.zero);
            // 创建一个位置控制柄
            Handles.PositionHandle(Vector3.zero, Quaternion.identity);
            // 创建一个滑动控制柄,可以沿某个方向滑动target
            Handles.Slider((target as TestInspector).transform.position, Vector3.zero);
    
            (target as TestInspector).transform.position = Handles.FreeMoveHandle((target as TestInspector).transform.position, Quaternion.identity, 2.0f, Vector3.zero, Handles.DrawRectangle);
           
            if (GUI.changed)
            {
                EditorUtility.SetDirty(target);
            }
        }
    
    }

      主要是使用Handles编辑器类来进行自定义,该类型提供了很多方便的操作接口,比如DrawLine、DrawCube、DrawBezier等。

      注意,不能在OnSceneGUI中使用SerializedObject。

      这篇帖子写得很不错:http://blog.csdn.net/lilanfei/article/details/7680802

  • 相关阅读:
    文本框输入内容提示消失的两种实现
    改变选择网页文字背景色
    软件增加一键处理功能
    全自动相机标定软件
    近景/低空摄影测量系统DPMatrix增加新功能
    DPMatrix软件新增了DEM/DOM制作模块,功能基本齐整!
    DPMatrix软件新增了图像匀光和色彩匹配批处理功能
    基于GPU/CUDA的全景图拼接
    基于GPU\CUDA并行处理技术的摄影测量
    软件与PATB平差数据交换
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/3923616.html
Copyright © 2011-2022 走看看