赞
踩
平时我们在搭建一个界面后都会给这个界面添加一个界面脚本,一般情况下都是普通的MonoBehaviour的。
此时脚本内定义的参数可以通过public或者特性[SerializeField]显示在inspector面板内。
但有时我们可能希望在面板上加一个按钮,然后能在编辑器模式下点击这个按钮就会执行脚本内的某个方法,此时就需要自定义这个面板。
代码如下示例:
普通界面脚本:
该脚本内有两个列表:templateDatas存储了实例的数据,templates存储了创建的实例对象
以及一些初始化的方法
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
-
- /// <summary>
- /// 东/西部概况界面
- /// </summary>
- public class GeneralSituation : MonoBehaviour
- {
- /// <summary>
- /// 示例物体
- /// </summary>
- private Template template;
- /// <summary>
- /// 显示区域
- /// </summary>
- private Transform content;
-
- /// <summary>
- /// 实例列表
- /// </summary>
- private List<Template> templates = new List<Template>();
-
- /// <summary>
- /// 实例数据列表
- /// </summary>
- [SerializeField]
- private List<TemplateData> templateDatas = new List<TemplateData>();
-
- /// <summary>
- /// 初始化实例
- /// </summary>
- public void InitTemplates()
- {
-
- }
-
- /// <summary>
- /// 初始化
- /// </summary>
- public void Init()
- {
- if(template == null)
- {
- template = this.transform.Find("Template").GetComponent<Template>();
- }
- if(content == null)
- {
- content = this.transform.Find("显示列表/Viewport/Content");
- }
- }
- }
Template与TemplateData数据脚本:
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
-
- /// <summary>
- /// 概况界面实例
- /// </summary>
- public class Template : MonoBehaviour
- {
- /// <summary>
- /// 标签
- /// </summary>
- [SerializeField]
- private Text title;
- /// <summary>
- /// 值
- /// </summary>
- [SerializeField]
- private Text value;
- /// <summary>
- /// 字体颜色
- /// </summary>
- [SerializeField]
- private Color color;
-
- /// <summary>
- /// 设置标签内容
- /// </summary>
- /// <param name="title"></param>
- public void SetTitle(string title)
- {
- this.title.text = title;
- this.title.color = color;
- }
-
- /// <summary>
- /// 设置值
- /// </summary>
- /// <param name="value"></param>
- public void SetValue(string value)
- {
- this.value.text = value;
- this.value.color = color;
- }
-
- /// <summary>
- /// 设置颜色
- /// </summary>
- /// <param name="color"></param>
- public void SetColor(Color color)
- {
- this.color = color;
- this.title.color = color;
- this.value.color = color;
- }
-
- /// <summary>
- /// 获取标签内容
- /// </summary>
- /// <returns></returns>
- public string GetTitle()
- {
- return this.title.text;
- }
- }
-
- /// <summary>
- /// 实例数据
- /// </summary>
- [Serializable]
- public class TemplateData
- {
- [SerializeField]
- public string title;
- [SerializeField]
- public string value;
- [SerializeField]
- public Color color;
-
- public TemplateData(string title, string value, Color color)
- {
- this.title = title;
- this.value = value;
- this.color = color;
- }
- }
界面编辑器脚本:
该脚本继承Editor,加上特性[CustomEditor(typeof(具体界面类))],然后实现OnInspectorGUI()方法即可自定义inspector显示面板,效果图如下
- using System.Collections;
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
-
- /// <summary>
- /// 东/西部概况界面编辑器
- /// </summary>
- [CustomEditor(typeof(GeneralSituation))]
- public class GeneralSituationEditor : Editor
- {
- GeneralSituation ui;
- GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(100f) };
- public override void OnInspectorGUI()
- {
- base.OnInspectorGUI();
- ui = (GeneralSituation)this.target;
-
- ui.Init();
-
- GUILayout.BeginVertical();
- //若设置了参数的显示效果,此处可注释掉
- for (int i = 0; i < ui.templateDatas.Count; i++)
- {
- GUILayout.BeginHorizontal();
- EditorGUILayout.LabelField("标题:", new GUILayoutOption[] { GUILayout.Width(30f) });
- ui.templateDatas[i].title = EditorGUILayout.TextField(ui.templateDatas[i].title, options);
- EditorGUILayout.LabelField("值:", new GUILayoutOption[] { GUILayout.Width(30f) });
- ui.templateDatas[i].value = EditorGUILayout.TextField(ui.templateDatas[i].value, options);
- EditorGUILayout.LabelField("颜色:", new GUILayoutOption[] { GUILayout.Width(30f) });
- ui.templateDatas[i].color = EditorGUILayout.ColorField(ui.templateDatas[i].color, options);
-
- if (GUILayout.Button("-", new GUILayoutOption[] { GUILayout.Width(20f) }))
- {
- ui.templateDatas.Remove(ui.templateDatas[i]);
- }
- GUILayout.EndHorizontal();
- }
-
- if (GUILayout.Button("+", new GUILayoutOption[] { GUILayout.Width(20f) }))
- {
- ui.templateDatas.Add(new TemplateData("", "", Color.white));
- }
-
- //可注释
- if (GUILayout.Button("确定", new GUILayoutOption[] { GUILayout.Width(100f) }))
- {
- ui.InitTemplates();
- }
-
- GUILayout.EndVertical();
- }
- }
效果图:
若要修改参数在inspector面板显示,需要新建一个脚本继承PropertyDrawer,然后添加特性[CustomPropertyDrawer(typeof(参数类名))],然后实现OnGUI()方法,示例如下
TemplateDataDrawer:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
-
- /// <summary>
- /// 实例数据编辑器
- /// </summary>
- [CustomPropertyDrawer(typeof(TemplateData))]
- public class TemplateDataDrawer : PropertyDrawer
- {
- public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
- {
- EditorGUI.BeginProperty(position, label, property);
- //FocusType.Passive 使用Tab键切换时不会被选中,FocusType.Keyboard 使用Tab键切换时会被选中
- position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
- //不让indentLevel层级影响到同一行的绘制,因为PropertyDrawer在很多地方都有可能被用到,可能出现嵌套使用
- var indent = EditorGUI.indentLevel;
- EditorGUI.indentLevel = 0;
- //定义各数据显示区域位置与大小
- var titleRect = new Rect(position.x, position.y,100, position.height);
- var valueRect = new Rect(position.x + 105, position.y, 50, position.height);
- var colorRect = new Rect(position.x + 160, position.y, 50, position.height);
- //设置参数对应位置与大小
- EditorGUI.PropertyField(titleRect, property.FindPropertyRelative("title"), GUIContent.none);
- EditorGUI.PropertyField(valueRect, property.FindPropertyRelative("value"), GUIContent.none);
- EditorGUI.PropertyField(colorRect, property.FindPropertyRelative("color"), GUIContent.none);
- EditorGUI.indentLevel = indent;
- EditorGUI.EndProperty();
- }
- }
效果如图:
两者结合即可实现inspector面板的自定义效果 ,当然也可以分开使用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。