UIToolkit示例

参考 https://docs.unity3d.com/Manual/UIE-uxml-examples.html

实现纯图片按钮

    .image-button {
        background-color: rgba(0, 0, 0, 0);
        -unity-background-image-tint-color: rgb(200, 200, 200);
        border-left-width: 0;
        border-right-width: 0;
        border-top-width: 0;
        border-bottom-width: 0;
    }

    .image-button:hover:enabled {
        -unity-background-image-tint-color: rgb(255, 255, 255);
    }

    .image-button:hover:active:enabled {
        -unity-background-image-tint-color:  #888888;
    }

列表设置元素间距

  • 设置 ListView 的 fixItemHeight=50
  • 创建列表元素时,列表元素会自动设置高为50,添加一个子元素,设置height=40,则剩下的10做为间距
  • 接下来就是把鼠标悬停、选中效果从列表元素转移到子元素上
    • 创建列表元素时,给子元素添加 item-back 样式,或直接在UIBuilder中添加
    • 在界面中引用如下样式文件,就2个作用,清除原本的列表元素样式,设置子元素样式
          .unity-list-view__item {
              background-color: rgba(0, 0, 0, 0);
          }
      
          .unity-list-view__item:hover {
              background-color: rgba(0, 0, 0, 0);
          }
      
          .unity-list-view__item:checked {
              background-color: rgba(0, 0, 0, 0);
          }
      
          .unity-list-view__item:checked .item-back {
              border-left-color: rgba(12, 122, 237, 255);
              border-right-color: rgba(12, 122, 237, 255);
              border-top-color: rgba(12, 122, 237, 255);
              border-bottom-color: rgba(12, 122, 237, 255);
          }
      
          .unity-list-view__item:hover .item-back {
              border-left-color: rgba(85, 162, 242, 255);
              border-right-color: rgba(85, 162, 242, 255);
              border-top-color: rgba(85, 162, 242, 255);
              border-bottom-color: rgba(85, 162, 242, 255);
          }
      

Editor模式下自定义Tooltip

主要有2个难点

  1. 让窗口适配文本大小
    获取文本大小有2种方案
    1. 监听Label的 GeometryChangedEvent 事件,通过 resolvedStyle 获取大小
      Rect(element.resolvedStyle.left, element.resolvedStyle.top, element.resolvedStyle.width, element.resolvedStyle.height)
    2. 使用 TextElement.MeasureTextSize 直接计算文本占用的大小
  2. 让窗口自动显示在控件的上下左右合适的地方
    当前也有2种方案
    1. 使用unity提供的自动对齐
      有2个api可以实现,EditorWindow.ShowAsDropDown 和 PopupWindow.Show
      这2个api都可以显示弹窗,区别就在于 PopupWindow 可以在窗口显示后更改窗口大小,而 EditorWindow.ShowAsDropDown 则不行
      而上面获取文本大小又需要窗口显示后才能获取,因此最终方案是使用 PopupWindow.Show
      PopupWindow 会在 OnGUI 函数中调用 FitWindowToContent 实现实时更新窗口大小,最终是调用 ContainerWindow.GetDropDownRect ,这是内部函数
    2. 自己计算位置
      自己计算位置的最大问题是没找到获取所有屏幕的屏幕范围的方法
      操作系统是把所有显示器的显示范围都统一到一个虚拟坐标系中,只要能获取所有屏幕的显示范围,就可以计算出提示应该摆在哪里
      unity中只提供了 Display.displays 获取显示器大小,但缺少获取偏移的api
      最终实现是使用 1.1 + 2.1 来解决,也就是 PopupWindow.Show + 监听 GeometryChangedEvent
    public class CustomTooltip : PopupWindowContent
{
    private static CustomTooltip instance;
    private string tip;
    private Vector2 tipSize = new Vector2(100, 100);     //  给一个初始值
    private Label tooltipLabel;
    
    //  targetBounds 是需要提示的控件的边框
    public static void ShowTooltip(string text, Rect targetBounds)
    {
        HideTooltip();
        instance = new CustomTooltip(text);
        UnityEditor.PopupWindow.Show(targetBounds, instance);
    }

    public static void HideTooltip()
    {
        if (instance != null && instance.editorWindow != null)
        {
            try
            {
                instance.editorWindow.Close();
            } catch (Exception e) { }
        }
        instance = null;
    }

    public CustomTooltip(string tip)
    {
        this.tip = tip;
    }

    public override Vector2 GetWindowSize()
    {
        return tipSize;
    }

    public override void OnOpen()
    {
        InitializeUI();
        tooltipLabel.text = tip;
        tooltipLabel.RegisterCallback<GeometryChangedEvent>(OnFirstInit);
    }

    private void InitializeUI()
    {
        var root = editorWindow.rootVisualElement;

        //  root 的 flexDirection = FlexDirection.Column
        //  必须再添加一个 flexDirection = FlexDirection.Row 的元素,不然lable大小计算有问题
        VisualElement tooltipContainer = new VisualElement();
        tooltipContainer.style.flexDirection = FlexDirection.Row;
        root.Add(tooltipContainer);

        tooltipLabel = new Label();
        tooltipLabel.style.color = new Color(0.733f,0.733f,0.733f,1);
        tooltipLabel.style.backgroundColor = new Color(0.18f,0.18f,0.196f,1);
        tooltipLabel.style.fontSize = 12;
        tooltipLabel.style.position = Position.Absolute;
        tooltipLabel.style.paddingLeft = tooltipLabel.style.paddingRight = 8;
        tooltipLabel.style.paddingTop = tooltipLabel.style.paddingBottom = 5;
        tooltipContainer.Add(tooltipLabel);
    }

    //  用文本大小做为窗口大小
    private void OnFirstInit(GeometryChangedEvent evt)
    {
        tooltipLabel.UnregisterCallback<GeometryChangedEvent>(OnFirstInit);
        tipSize = new Vector2(instance.tooltipLabel.resolvedStyle.width, instance.tooltipLabel.resolvedStyle.height);
    }

    public override void OnClose()
    {
        instance = null;
    }

    public override void OnGUI(Rect rect)
    {
    }
}

public static class CustomTooltipExtensions
{
    public static void AddCustomTooltip(this VisualElement element, string tooltipText)
    {
        element.RegisterCallback<MouseEnterEvent>(evt =>
        {
            Rect rc = element.worldBound;
            // 使用 PopupWindow 会自动转换,就不需要在这里转换了
            // rc.position = rc.position + EditorWindow.mouseOverWindow.position.position;
            CustomTooltip.ShowTooltip(tooltipText, rc);
        });
        element.RegisterCallback<MouseLeaveEvent>(evt =>
        {
            CustomTooltip.HideTooltip();
        });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值