Unity editor expansion exercise project one

A robust project is indispensable for various expansion tools. Good expansion tools can not only facilitate development, but also be pleasing to the eye. I have written many expansion tools before, but they are mainly practical and have relatively low artistic requirements (it should be said that they are ugly). , in order to beautify the tool and improve the readability of the tool, next I am going to work hard on expanding the tool beautification, and record the learning record.

Screenshots of works

Insert image description here

Practice points

  1. Use of basic components
  2. GUI layout
  3. Interface beautification
  4. Built-in Icon usage
  5. Built-in GUIStyle usage

MEditorWindow

The derived class of EditorWindow is intended to be the base class for custom windows. Currently, it has very few functions.
The code will be added in the future as follows:


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

The code for the first exercise project
is as follows:


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);
        }
    }
}

Guess you like

Origin blog.csdn.net/weixin_42498461/article/details/129128563