Unity 自带 GUIStyle 效果查看器

在编写 Unity 的扩展工具时,可能会需要用到 GUIStyle 来添加额外的视觉效果,Unity 本身自带了一些默认的效果可供使用。以下就是一个自用的效果查看器的代码。
在此为了丰富视觉效果,自定义了一个 GUIStyle,并且额外添加了一个输出 GUIStyle 设置信息的功能。

using UnityEngine;
using UnityEditor;

/// <summary>
/// Unity 自带的 GUIStyle 效果查看器
/// </summary>
public class GUIStyleViewerUtil : EditorWindow
{
    /// <summary>
    /// 滑动条
    /// </summary>
    private Vector2 mScrollView = Vector2.zero;
    /// <summary>
    /// 寻找的样式名称
    /// </summary>
    private string mSearchStyle = "";
    /// <summary>
    /// 样式缓存
    /// </summary>
    private static GUIStyle mBtnStyle;

    [MenuItem("Util/GUIStyle 效果查看器")]
    private static void MenuClicked()
    {
        GetWindow<GUIStyleViewerUtil>("GUIStyle查看器", true);
        // 初始化一个按钮的样式
        mBtnStyle = GetBtnStyle();
    }

    private void OnGUI()
    {
        GUILayout.Space(20);

        // 设置一个查找的功能
        GUILayout.BeginHorizontal("HelpBox");
        GUILayout.Space(20);
        mSearchStyle = EditorGUILayout.TextField("", mSearchStyle, "SearchTextField");
        GUILayout.Label("", "SearchCancelButtonEmpty");
        GUILayout.EndHorizontal();

        // 设置滚动栏
        mScrollView = GUILayout.BeginScrollView(mScrollView);
        // 遍历并显示所有符合条件的 Unity 自带的 GUIStyle
        foreach (GUIStyle style in GUI.skin.customStyles)
        {
            if (style.name.ToLower().Contains(mSearchStyle.ToLower()))
            {
                GUILayout.Space(10);
                // 为了让显示的布局看着更舒服一些,需要以当前 style 为原型新建一个 GUIStyle
                // 因为接下来可能会对文字居中等方面进行调整,
                // 而如果直接更改原来的 style,则会导致系统中的对应 UI 样式和布局也发生改变
                GUIStyle tmp = new GUIStyle(style);
                DrawStyleItem(tmp);
            }
        }
        GUILayout.EndScrollView();
    }

    /// <summary>
    /// 绘制对应的 GUIStyle
    /// </summary>
    /// <param name="style"></param>
    private void DrawStyleItem(GUIStyle style)
    {

        GUILayout.BeginHorizontal("box", GUILayout.Height(style.fixedHeight));
        GUILayout.Space(20);
        // 获取按钮样式
        GUIStyle tmp = mBtnStyle;

        // 设置第一个按钮,点击后可以复制当前 GUIStyle 的名字信息
        if (GUILayout.Button("<color=#000000FF>复制到剪贴板</color>", tmp))
        {
            CommonUtil.CopyText(style.name);
        }

        GUILayout.Space(20);

        // 设置第二个按钮,点击后在控制台输出该 GUIStyle 的设置参数
        if (GUILayout.Button("<color=#FFFFFFFF>查看Style参数</color>", tmp))
        {
            ShowGUIStyleMsg(style.name);
        }
        GUILayout.Space(30);

        // 显示当前 GUIStyle 的名字
        EditorGUILayout.SelectableLabel(style.name);

        // 设置左右对称布局,以此为分界线,把前后的布局对称
        GUILayout.FlexibleSpace();

        // 设置文本居中显示
        style.alignment = TextAnchor.MiddleCenter;
        // 显示当前的样式及其名称
        EditorGUILayout.SelectableLabel(style.name, style);

        GUILayout.Space(100);

        // 单独显示样式
        EditorGUILayout.SelectableLabel("", style, 
        								GUILayout.Height(style.fixedHeight),
        							 	GUILayout.Width(style.fixedWidth));
        GUILayout.Space(100);

        GUILayout.EndHorizontal();
    }

    /// <summary>
    /// 创建一个按钮样式,用来作为本界面中的按钮基础
    /// </summary>
    /// <returns></returns>
    public static GUIStyle GetBtnStyle()
    {
        // 使用系统自带的 "AC Button" 样式作为原型,因为 "AC Button" 本身就具有点击效果了
        GUIStyle style = new GUIStyle("AC Button");

        // 将样式的点击时的效果图,替换为系统自带的 "flow node 4 on" 样式
        GUIStyle active = new GUIStyle("flow node 4 on");
        style.active.background = active.normal.background;

        // 将平时按钮的效果图,替换为系统自带的 "flow node 4" 样式
        GUIStyle normal = new GUIStyle("flow node 4");
        style.normal.background = normal.normal.background;

        // 参考 "flow node 4" 的内部参数,设置一些图片的参数。
        // 如果不设置的话,则图片会按照原 "AC Button" 的样式进行显示
        // 因为图片不一样,所以会有显示上的问题。
        style.stretchHeight = true;
        style.stretchWidth = true;
        style.border = new RectOffset(11, 11, 11, 15);
        style.margin = new RectOffset(0, 0, 0, 0);
        style.padding = new RectOffset(0, 0, 0, 0);
        style.overflow = new RectOffset(7, 7, 6, 9);

        // 进行文本方面的设置
        style.alignment = TextAnchor.MiddleCenter;
        style.fontSize = 30;
        style.richText = true;

        return style;
    }

    /// <summary>
    /// 展示指定的 GUI 样式的一些数值
    /// </summary>
    /// <param name="style"></param>
    public void ShowGUIStyleMsg(string style)
    {
        // 清空控制台信息,防止混淆
        EditorUtil.ClearConsole();

        GUIStyle tmp = new GUIStyle(style);
        Debug.Log("Style Name: " + tmp.name);
        Debug.Log("Style Normal: " + tmp.normal.background);
        Debug.Log("Style Normal Color: " + tmp.normal.textColor);
        Debug.Log("Style Active: " + tmp.active.background);
        Debug.Log("Style Active Color: " + tmp.active.textColor);
        Debug.Log("Style Hover: " + tmp.hover.background);
        Debug.Log("Style Hover Color: " + tmp.hover.textColor);
        Debug.Log("Style Focused: " + tmp.focused.background);
        Debug.Log("Style Focused Color: " + tmp.focused.textColor);
        Debug.Log("Style border: " + tmp.border);
        Debug.Log("Style margin: " + tmp.margin);
        Debug.Log("Style padding: " + tmp.padding);
        Debug.Log("Style overflow: " + tmp.overflow);
        Debug.Log("Style fixedWidth: " + tmp.fixedWidth);
        Debug.Log("Style fixedHeight: " + tmp.fixedHeight);
        Debug.Log("Style stretchWidth: " + tmp.stretchWidth);
        Debug.Log("Style stretchHeight: " + tmp.stretchHeight);
        Debug.Log("Style lineHeight: " + tmp.lineHeight);
        Debug.Log("Style Font: " + tmp.font);
        Debug.Log("Style Font Size: " + tmp.fontSize);
    }
}

完成后的效果如下所示:
在这里插入图片描述

注意:

需要注意的是自定义的按钮要完全使用新创建的 GUIStyle,可以通过 Unity 已有的样式作为模板创建,但是不要修改原有样式。

// 遍历并显示所有符合条件的 Unity 自带的 GUIStyle
foreach (GUIStyle style in GUI.skin.customStyles)
{
	if (style.name.ToLower().Contains(mSearchStyle.ToLower()))
    {
    	GUILayout.Space(10);              
        GUIStyle tmp = new GUIStyle(style);
        DrawStyleItem(tmp);
    }
}

由于我在后续代码中使用了文本居中的设置,所以此处必须创建新的 GUIStyle,否则就会修改系统自带的效果,最直观的影响就是控制台 Console 的输出结果也会全部居中显示。如下图所示:
在这里插入图片描述
最后还有一点需要注意的是EditorUtil.ClearConsole();这个方法是一个清空控制台输出的方法,目的是防止过多信息的混淆。定义如下:

/// <summary>
/// 通过脚本清空 Unity 控制台日志信息
/// </summary>
public static void ClearConsole()
{            
	Assembly assembly = Assembly.GetAssembly(typeof(SceneView));
    Type logEntries = assembly.GetType("UnityEditor.LogEntries");
    MethodInfo clearConsoleMethod = logEntries.GetMethod("Clear");
    clearConsoleMethod.Invoke(new object(), null);
    Debug.Log("已清空控制台日志信息!");
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值