Unity 编辑器拓展练习项目一

一个健壮的工程里面少不了各种拓展工具,好的拓展工具不仅可以方便开发,还能够赏心悦目,以前也写过许多的拓展工具,主要偏实用对工具的美术要求比较低(应该说是很难看),为了美化工具提高工具的可读性,接下来准备在拓展工具美化这一块用用力,并记载一下学习记录。

作品截图

在这里插入图片描述

练习重点

  1. 基本组件的使用
  2. GUI布局
  3. 界面美化
  4. 内置Icon使用
  5. 内置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);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42498461/article/details/129128563