UE 不修改源码实现遮罩控件 (Mask Widget)

news/2024/9/22 17:24:05

本文内容的参考和灵感来自以下链接

GitHub - inkiu0/MaskWidget: UE4 MaskWidget

GitHub - JanSeliv/CustomShapeButton: Open-source plugin that allows to make buttons of any shape in UE5.4

在 UE 有一个很麻烦的地方,Slate 事件不是按照堆叠顺序传递的,就会形成以下现象

上图是使用 CustomShapeButton 和 Button 相叠,形成的一个使用场景,遮罩按钮显示在普通按钮上面,虽然遮罩按钮没有处理鼠标事件,但是鼠标事件也不会传递给普通按钮

我们调试一下看看怎么回事

我们新建一个 SWidget ,然后在 UI 处理事件的函数断点,例如 OnMouseButtonDown 函数

这是 UI 的布局

查看堆栈数据,序号 47 是我们的 MainWidget ,但它后面只有两个 Widget 一个是 Canvas Panel 另一个是 MaskWidget (新建的 SWidget 类型),这里可以得出一个结论,但鼠标在 MaskWidget 上进行点击时,被 MaskWidget 遮住的 Button 是不会进入分发事件的队列的(或者说同级的 Widget 是不会进入另一个同级 Widget 的 Slate 事件队列,具体原因可以看图中函数的源码 FSlateApplication::ProcessMouseButtonDownEvent)

那么下面将开始在不修改源码的情况下,实现遮罩这一需求
我的核心思路是在 Tick 的时候根据鼠标所在的像素数据来更改 MaskWidget 的 Visibility 变量(Visibility 不是 Visible 时是不会进入发送事件的队列的)

首先一点,如何在 Tick 时获得鼠标位置,我们去溯源 MouseEvent 这个参数的形成过程

我们在这里可以发现 SlateApplication 有一个 CurrentCursorPosition 的变量可以读取,它就是当前鼠标位置

那么如何判断鼠标是否在 Widget 内呢,我们参考一下 UE 在获得当前鼠标 Hover 的 Widgets 时是怎么做的,具体是 FHittestGrid::GetHitIndexFromCellIndex 函数

我们从 FHittestGrid 复制一些局部函数过来

然后构成这个函数的使用条件,我们在 OnPaint 缓存 FHittestGrid 和 FGeometry 

这样就可以在 Tick 中判断鼠标是否在 Widget 内

接下里实现一下遮罩材质,随便连一下(Texture 是从 inkiu0 的 MaskWidget 拿的)

下一步就是渲染材质到尺寸和 MaskWidget 一样的 RenderTaget 上,当我们将鼠标位置转换到 Widget 的本地位置,鼠标位置 Hover 的像素等于 RenderTarget 在该位置的像素(此处参考了 CustomShapeButton 的思路)

那到这里差不多就实现了

看看效果

(实现并不完善,后续实际应用遇到什么问题再完善吧😂)

全部代码在以下链接

代码浏览 - UE-DM-Tool

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/46991.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

【服务器】Ubuntu虚拟内存设置

引子 最近服务器内存老是爆掉,64G的内存对于四五个人同时使用还是有点勉强,上网查询了一下虚拟内存的教程,本博客记录一下方法。swap内存设置 假设你想将swap文件放在/mnt/data/mem目录下,以下是详细的步骤: 创建并启用Swap文件创建目录(如果目录不存在): sudo mkdir -…

作业7

task1. 点击查看代码 // 将图书信息写入文本文件data1.txt // 再从文件中读取图书信息,打印输出到屏幕上,并显示行号#include <stdio.h>#define N 80 #define M 100typedef struct {char name[N]; // 书名 char author[N]; // 作者 } Book;// 函数声明 void func1()…

使用cloudflare-works搭建自己docker加速源

在网上看到了许多教程,基本上部署都是手动的,docker镜像都要手动输入选择重新部署。要么都是些基本镜像仓库。 视频地址:【CloudFlare搭建doker加速源。都这么长时间了,你的docker还是跑不通吗?】 https://www.bilibili.com/video/BV1F533eHEsB/?share_source=copy_web&a…

AI 大模型企业应用实战(06)-初识LangChain

LLM大模型与AI应用的粘合剂。 1 langchain是什么以及发展过程 LangChain是一个开源框架,旨在简化使用大型语言模型构建端到端应用程序的过程,也是ReAct(reason+act)论文的落地实现。2022年10月25日开源 54K+ star 种子轮一周1000万美金,A轮2500万美金 11个月里累计发布200多…

创新实现(九)——博客处理

博客部分 当用户需要针对OJ上的比赛以及题目进行相关讨论的时候,OJ平台给大家一个博客平台供大家交流讨论。博客部分中利用blogs.php文件进行最近前10个博客的显示,用户可以利用右上角的按钮查看自己的博客情况以及自己写一个博客。 博客总览blogs.php文件用于生成一个博客总…

面向对象大作业总结(三)

一.前言:本次博客是对第七到八次大作业进行总结。我认为第七次大作业相比于同一道题来说,并没有进行太大的改变,因为它不需要考虑每个元件左右两端到底电位状态如何,也就是在前两次的基础上增加了一些并联电路,这个时候我们只要在MainLine类里新增并联以及串联电路的判断就…

java使用@Controller注解跳转到thmyleaf页面时候报错

报错如下###### 当我使用RestController时候接口可以得到返回的对象↓但是查看RestController和Controller的区别之后:也就是说@RestController返回的是一个对象,@Controller默认情况下,方法的返回值会被解析为一个视图名称,并寻找与该名称匹配的视图进行渲染。这意味着返回…

Centos下安装ffmpeg

源安装第一种方式:首先需要安装yum源: 这个源安装的ffmpeg版本是3.4yum install epel-release yum install -y https://mirrors.ustc.edu.cn/rpmfusion/free/el/rpmfusion-free-release-7.noarch.rpm然后可以安装ffmpegyum install -y ffmpeg ffmpeg-devel第二种方式: 换一个…