一个健壮的工程里面少不了各种拓展工具,好的拓展工具不仅可以方便开发,还能够赏心悦目,以前也写过许多的拓展工具,主要偏实用对工具的美术要求比较低(应该说是很难看),为了美化工具提高工具的可读性,接下来准备在拓展工具美化这一块用用力,并记载一下学习记录。
作品截图
练习重点
- 基本组件的使用
- GUI布局
- 界面美化
- 内置Icon使用
- 内置GUIStyle使用
MEditorWindow
EditorWindow的派生类,准备做自定义窗口的基类,目前功能很少,后期持续补充
代码如下:
using UnityEditor;
using UnityEngine;
namespace S.Editor
{
public class MEditorWindow : EditorWindow
{
protected virtual void OnGUI()
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
OnTitleGUI();
EditorGUILayout.EndHorizontal();
OnBodyGUI();
}
/// <summary>
/// 绘制标题区域
/// </summary>
protected virtual void OnTitleGUI()
{
}
/// <summary>
/// 绘制主体区域
/// </summary>
protected virtual void OnBodyGUI()
{
}
/// <summary>
/// 拷贝字符串到剪贴板
/// </summary>
protected void CopyString(string value)
{
TextEditor textEditor = new TextEditor();
textEditor.text = value;
textEditor.OnFocus();
textEditor.Copy();
}
}
}
EditorDemo0
第一个练习项目
代码如下:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace S.Editor
{
public class EditorDemo0 : MEditorWindow
{
private SearchField searchField;
private string searchString;
private GUIContent titleButtonGUIContent;
private GUIContent bodyTitleGUIContent;
private GUIStyle bodyTitleStyle;
private List<string> leftList;
private List<string> rightList;
private string addName_left, addName_right;
private int selectedId_left, selectedId_right;
private GUIContent dataTitleContent;
[MenuItem("Tools/Demo0")]
static void Demo0()
{
EditorDemo0 window = GetWindowWithRect<EditorDemo0>(new Rect(0, 0, 510, 530), false, "练习一");
window.titleContent.image = EditorGUIUtility.IconContent("SettingsIcon").image;
window.Show();
}
void OnEnable()
{
searchField = new SearchField();
titleButtonGUIContent = new GUIContent("学生管理", "学生信息列表");
titleButtonGUIContent.image = EditorGUIUtility.IconContent("Shadow Icon").image;
bodyTitleGUIContent = new GUIContent();
bodyTitleGUIContent.image = EditorGUIUtility.IconContent("tree_icon_frond").image;
bodyTitleStyle = new GUIStyle();
bodyTitleStyle.alignment = TextAnchor.MiddleCenter;
bodyTitleStyle.fontSize = 20;
bodyTitleStyle.normal.textColor = Color.green;
dataTitleContent = new GUIContent();
dataTitleContent.image = EditorGUIUtility.IconContent("d_console.infoicon.sml").image;
leftList = new List<string>();
rightList = new List<string>();
}
protected override void OnTitleGUI()
{
GUILayout.Box(titleButtonGUIContent, EditorStyles.toolbarButton);
GUILayout.FlexibleSpace();
searchString = SearchInputToolbarGUI(searchString);
}
protected override void OnBodyGUI()
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(5);
EditorGUILayout.BeginVertical();
OnLeftGUI();
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
OnRightGUI();
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}
//绘制左侧部分
void OnLeftGUI()
{
EditorGUILayout.BeginVertical("grey_border", GUILayout.Width(250), GUILayout.Height(400));
OnLeftBodyGUI();
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical("grey_border", GUILayout.Width(250), GUILayout.Height(100));
OnLeftDataGUI();
EditorGUILayout.EndVertical();
}
//绘制左侧主体
void OnLeftBodyGUI()
{
bodyTitleGUIContent.text = "一年级";
EditorGUILayout.LabelField(bodyTitleGUIContent, bodyTitleStyle);
addName_left = ControllerGUI(addName_left, value => leftList.Add(value));
DrawUsers(true);
}
//绘制左侧信息
void OnLeftDataGUI()
{
dataTitleContent.text = "一年级选中人物详情:";
EditorGUILayout.LabelField(dataTitleContent);
if (selectedId_left < 0 || selectedId_left >= leftList.Count) return;
string name = leftList[selectedId_left];
GUILayout.Label("姓名:" + name);
GUILayout.Label("名字长度:" + name.Length);
}
//绘制右侧部分
void OnRightGUI()
{
EditorGUILayout.BeginVertical("grey_border", GUILayout.Width(250), GUILayout.Height(400));
OnRightBodyGUI();
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical("grey_border", GUILayout.Width(250), GUILayout.Height(100));
OnRightDataGUI();
EditorGUILayout.EndVertical();
}
//绘制右侧主体
void OnRightBodyGUI()
{
bodyTitleGUIContent.text = "二年级";
EditorGUILayout.LabelField(bodyTitleGUIContent, bodyTitleStyle);
addName_right = ControllerGUI(addName_right, value => rightList.Add(value));
DrawUsers(false);
}
//绘制右侧信息
void OnRightDataGUI()
{
dataTitleContent.text = "二年级选中人物详情:";
EditorGUILayout.LabelField(dataTitleContent);
if (selectedId_right < 0 || selectedId_right >= rightList.Count) return;
string name = rightList[selectedId_right];
GUILayout.Label("姓名:" + name);
GUILayout.Label("名字长度:" + name.Length);
}
// 绘制班级控制部分
string ControllerGUI(string addName, Action<string> addCallBack)
{
EditorGUILayout.BeginHorizontal();
addName = EditorGUILayout.TextField(addName);
if (GUILayout.Button("增加"))
{
GUI.FocusControl(null);
addCallBack?.Invoke(addName);
return null;
}
EditorGUILayout.EndHorizontal();
return addName;
}
//绘制用户信息
void DrawUsers(bool isLeft)
{
if (leftList == null && isLeft) return;
if (rightList == null && !isLeft) return;
List<string> userInfos = isLeft ? leftList : rightList;
int selectedId = isLeft ? selectedId_left : selectedId_right;
string name;
for (int i = 0; i < userInfos.Count; i++)
{
name = userInfos[i];
if (!CheckSearch(name)) continue;
if (i == selectedId) EditorGUILayout.BeginHorizontal("SelectionRect");
else EditorGUILayout.BeginHorizontal();
if (GUILayout.Button(name, EditorStyles.label))
{
if (isLeft) selectedId_left = i;
else selectedId_right = i;
}
EditorGUILayout.EndHorizontal();
}
}
//绘制搜索框
string SearchInputToolbarGUI(string value, Action<string> changedAct = null, params GUILayoutOption[] options)
{
EditorGUI.BeginChangeCheck();
string result = searchField.OnToolbarGUI(value, options);
if (EditorGUI.EndChangeCheck()) changedAct?.Invoke(result);
return result;
}
// 判断名字是否符合搜索规则
bool CheckSearch(string name)
{
if (string.IsNullOrEmpty(searchString)) return true;
return Regex.IsMatch(name, searchString, RegexOptions.IgnoreCase);
}
}
}