前文:
本章节会对InspectorEditor(属性编辑器)的创建方式进行叙述.
正文:
1.代码最终效果
2. 架构阐述
一个InspectorEditor(属性编辑器)产生直接对应着一个继承MonoBehaviour的脚本文件,脚本文件中定义着不同的属性以供InspectorEditor(属性编辑器)去实现。我们可以通过EditorGUILayout/GUILayout来实现InspectorEditor(属性编辑器)界面。
3. EditorGUILayout脚本分析
EditorGUILayout 是绘制InspectorEditor(属性编辑器)的脚本类,脚本内部方法大致分为两类,一类是:手动布局,另外一类是:组件绘制。
4. 开始实现切入正题
4.1 大家都知道拓展器的脚本都需要放置在Editor文件下进行预编译,所以我们也为自己的项目创建一个Editor目录。额外在创建一个Script目录存储脚本文件。
4.2 在Script文件下创建继承自MonoBehaviour的脚本类,维护自定义编辑器属性.有人会问这个类到底用来干什么的,以当下的理解来讲,用于存储编辑器数据用的.下面将我创建的代码贴到下面以供大家参考。
using UnityEngine;using System.Collections;public enum VirtualRoomColor{ Black, Blue, Clear, Cyan, Gray, Green, Magenta, Red, White, Yellow}public enum VirtualRoomAudioEffect{ Custom, Default, Cathedral, Office, Outside}public enum VirtualRoomMaterial{ Custom, AcousticTile, AcrylicGlass, Air, Asbestos, BrickWall, Dirt, ExpandedPolystyrene, Fiberboard, Fiberglass, Glass, GlazedTile, Grass, Gravel, Hardwood, HeavyCarpet, HeavyCurtain, LeatherUpholstery, Linoleum, Marble, MineralWool, OfficeCarpet, PaintedWood, Plaster, PolishedWood, Polycarbonate, PolyurethaneFoam, RoughConcrete, Rubber, Sand, SealedConcrete, Tapestry, Vinyl}public class VirtualRoomStruct{ private VirtualRoomMaterial m_RoomMaterial; private float m_Vale; public VirtualRoomMaterial RoomMaterial { get { return m_RoomMaterial; } set { m_RoomMaterial = value; } } public float Vale { get { return m_Vale; } set { m_Vale = value; } }}public enum VirtualRoomWallDirection{ Left, Right, Back, Front, Ceiling, Floor}public class SR3DVirtualRoom : MonoBehaviour{ private Vector3 m_RoomSize = new Vector3(100f, 40f, 50f); private VirtualRoomColor m_RoomColor = VirtualRoomColor.White; private VirtualRoomAudioEffect m_RoomEffect = VirtualRoomAudioEffect.Default; private VirtualRoomStruct m_LeftWall = new VirtualRoomStruct(); private VirtualRoomStruct m_RightWall = new VirtualRoomStruct(); private VirtualRoomStruct m_FrontWall = new VirtualRoomStruct(); private VirtualRoomStruct m_BackWall = new VirtualRoomStruct(); private VirtualRoomStruct m_Ceiling = new VirtualRoomStruct(); private VirtualRoomStruct m_Floor = new VirtualRoomStruct(); private const float m_Interval = 3f; public Vector3 RoomSize { get { return m_RoomSize; } set { m_RoomSize = value; } } public VirtualRoomColor RoomColor { get { return m_RoomColor; } set { m_RoomColor = value; } } public VirtualRoomAudioEffect RoomEffect { get { return m_RoomEffect; } set { m_RoomEffect = value; } } public VirtualRoomStruct LeftWall { get { return m_LeftWall; } set { m_LeftWall = value; } } public VirtualRoomStruct RightWall { get { return m_RightWall; } set { m_RightWall = value; } } public VirtualRoomStruct FrontWall { get { return m_FrontWall; } set { m_FrontWall = value; } } public VirtualRoomStruct BackWall { get { return m_BackWall; } set { m_BackWall = value; } } public VirtualRoomStruct Ceiling { get { return m_Ceiling; } set { m_Ceiling = value; } } public VirtualRoomStruct Floor { get { return m_Floor; } set { m_Floor = value; } }}
4.3 在Editor目录创建我们的InspectorEditor(属性编辑器)脚本文件,并放入以下代码.(具体代码含义见注释)
using System;using UnityEngine;using UnityEditor;using System.Collections;// 第1步:对SR3DVirtualRoom脚本进行编辑器重定义[CustomEditor(typeof(SR3DVirtualRoom))]public class SR3DGUIVirtualRoom : Editor{ private bool m_GroupState = true; // 第2步:重写拓展编辑器方法 public override void OnInspectorGUI() { // 第3步:获取到对应实例 SR3DVirtualRoom room = target as SR3DVirtualRoom; // 定义一个垂直自动排序的布局 EditorGUILayout.BeginVertical(); // 添加空格行 EditorGUILayout.Space(); // 添加一个Label标签 EditorGUILayout.LabelField("Room Name", "VirtualRoom"); EditorGUILayout.Space(); // 添加一个Vector3类型的数据,用户编辑玩的数据将转存到我们的SR3DVirtualRoom属性中 room.RoomSize = EditorGUILayout.Vector3Field("Room Size", room.RoomSize); EditorGUILayout.Space(); // 添加一个枚举类型的数据显示 room.RoomColor = (VirtualRoomColor)EditorGUILayout.EnumPopup("Room Color", room.RoomColor); EditorGUILayout.Space(); room.RoomEffect = (VirtualRoomAudioEffect) EditorGUILayout.EnumPopup("Room Audio Effect", room.RoomEffect); EditorGUILayout.EndVertical(); // 密度、反射设置 EditorGUILayout.Space(); // 添加可折叠标签 m_GroupState = EditorGUILayout.Foldout(m_GroupState, "Virtual Room Struct"); if (m_GroupState) { if (Selection.activeTransform) { EditorGUILayout.BeginVertical(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" Left Wall"); room.LeftWall.RoomMaterial = (VirtualRoomMaterial)EditorGUILayout.EnumPopup(room.LeftWall.RoomMaterial); room.LeftWall.Vale = EditorGUILayout.Slider(room.LeftWall.Vale, 0, 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" Right Wall"); room.RightWall.RoomMaterial = (VirtualRoomMaterial)EditorGUILayout.EnumPopup(room.RightWall.RoomMaterial); room.RightWall.Vale = EditorGUILayout.Slider(room.RightWall.Vale, 0, 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" Front Wall"); room.FrontWall.RoomMaterial = (VirtualRoomMaterial)EditorGUILayout.EnumPopup(room.FrontWall.RoomMaterial); room.FrontWall.Vale = EditorGUILayout.Slider(room.FrontWall.Vale, 0, 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" Back Wall"); room.BackWall.RoomMaterial = (VirtualRoomMaterial)EditorGUILayout.EnumPopup(room.BackWall.RoomMaterial); room.BackWall.Vale = EditorGUILayout.Slider(room.BackWall.Vale, 0, 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" Ceiling"); room.Ceiling.RoomMaterial = (VirtualRoomMaterial)EditorGUILayout.EnumPopup(room.Ceiling.RoomMaterial); room.Ceiling.Vale = EditorGUILayout.Slider(room.Ceiling.Vale, 0, 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" Floor"); room.Floor.RoomMaterial = (VirtualRoomMaterial)EditorGUILayout.EnumPopup(room.Floor.RoomMaterial); room.Floor.Vale = EditorGUILayout.Slider(room.Floor.Vale, 0, 1); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } } if (!Selection.activeTransform) { m_GroupState = false; } }}
4.4 思路整理
所有的编辑器都可以根据以下思路进行编写,完成代码后返回UNITY3D编辑器重新加载编译后,将脚本挂载到游戏对象中则显示出自定义编辑器内容,下一篇则对序列属性进行讲解,序列化属性是一种更简单的编辑器编写方式,但也要结合当前基础来编写才会更高效!
时间: 2024-10-10 21:35:57