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

  • 相关阅读:
    HDU 5835 Danganronpa 贪心
    HDU 5842 Lweb and String 水题
    HDU 5832 A water problem 水题
    Codeforces Beta Round #14 (Div. 2) A. Letter 水题
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem K. UTF-8 Decoder 模拟题
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem I. Alien Rectangles 数学
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem H. Parallel Worlds 计算几何
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem F. Turning Grille 暴力
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem C. Cargo Transportation 暴力
    Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem G. k-palindrome dp
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/3923616.html
Copyright © 2011-2022 走看看