当前位置: 首页 > news >正文

UE--Slate 焦点、捕获,输入处理与玩家控制器的关系

Slate 焦点、捕获,输入处理与玩家控制器的关系

在虚幻引擎开发中我们必不可少的会接触到键盘输入、鼠标输入、ui上各种焦点问题、鼠标被ui捕获等等

以及与玩家控制器之间的关系(也就是玩家控制器 或者 本地玩家(玩家输入 UPlayerInput) 是如何拿到输入事件的)

这个问题一直困扰我 我今天就记录一下自己当前浅薄的知识

1、Slate如何绘制到屏幕上

1.首先我们需要知道Slate中的几个基本类型

1.SCompoundWidget(单子控件容器)
  • 定义:只有一个 ChildSlot,可以包裹一个控件(SWidget)
  • 用途:自定义复合控件。
  • 例子:SButton、SScrollBox、SWindow
2.SPanel(多子控件容器)
  • 定义 :可以拥有多个 Slot,每个 Slot 存一个子控件(SWidget)。
  • 用途 :用于布局、排列、聚合多个控件。
  • 例子 :SVerticalBox、SOverlay、SDPIScaler、SConstraintCanvas(大家熟悉的画布面板)
3.SLeafWidget(叶子控件容器)
  • 定义 :没有Slot,也就是没有子控件。
  • 用途 :负责绘制或显示具体内容
  • 例子 :STextBlock、SImage
4.SWidget (控件)
  • Slate控件顶层父类
  • 自定义控件( 一般来说不用它)

2.Slate绘制流程

先来一个简易的类图

在这里插入图片描述

简易的流程图
在这里插入图片描述
在这里插入图片描述

从图上看出来了 slate会从树的顶部 一直往下进行遍历
不断的调用
SWidget::Paint
SWidget::OnPaint

也就是说 你想让ue显示你新写的的Slate UI
你需要添加到某个已经在屏幕上显示的Slate 的控件中的Slot里面就可以了

2.Slate响应输入

Slate响应输入的关键函数都在
FSlateApplication类里面
类似ProcessMouseButtonDownEvent这类函数

1.从鼠标左键开始

Slate响应鼠标按键按下时
会调用到 FSlateApplication::ProcessMouseButtonDownEvent 函数

先来个简易的流程图
在这里插入图片描述

从上图我们看出最关键的地:
FEventRouter::Route <>
FEventRouter::FToLeafmostPolicy 迭代策略系列
控件路径
捕获路径
键盘焦点路径

下面我们就说说这几个路径

2.控件路径

  • 控件路径:主要是用于 在鼠标没有被任何Slate控件捕获的情况下
    我们拥有的Slate控件树从根到最后的叶子的迭代路径
  • 由来:FSlateApplication::Tick 函数中 调用的 SWidget::Paint中调用的FHittestGrid::AddWidget函数中进行添加的
  • 控件需要可视与可交互 才会被收集
  • 当然响应时也做出了可交互的判断

3.键盘焦点路径

  • 键盘输入响应的控件路径
    其实就是FSlateUser::WeakFocusPath
  • 由来:
    这个会在每次调用 FSlateUser::SetFocusPath
    进行设置 一般是1直接调用 FSlateApplication::SetUserFocus
    这个会将当前要设置的焦点控件 从根到自己为止的控件迭代路径 保留到WeakFocusPath
    让键盘输入事件时使用

4.捕获路径

  • Slate控件捕获鼠标时 缓存的控件路径
  • 鼠标事件响应时会做 SlateUser捕获鼠标与否做 控件迭代路径的不同
  • 由来:FSlateApplication::ProcessReply 函数中 FSlateUser::SetPointerCaptor会将捕获的控件为止的路径 保存到FSlateUser::PointerCaptorPathsByIndex
  • 返回的 FReply 也是在FSlateApplication::ProcessReply中进行处理的

3.FSlateApplication::ProcessReply函数

  • 触发这个函数会在引擎的Tick里触发
  • FEventRouter::Route <>中
  • 这个函数处理了FReply
  • FSlateApplication::SetUserFocus
  • FSlateUser::SetPointerCaptor

Tick触发时主要是处理ULocalPlayer::SlateOperations 也是 FReply

好像鼠标移动也会进行处理

4.Slate键盘响应

  • FSlateApplication::ProcessKeyDownEvent
    在这个函数中我们发现 它直接使用了焦点路径进行迭代的
		TSharedRef<FWidgetPath> EventPathRef = SlateUser->GetFocusPath();const FWidgetPath& EventPath = EventPathRef.Get();// Switch worlds for widgets inOnPreviewMouseButtonDown the current pathFScopedSwitchWorldHack SwitchWorld(EventPath);// Tunnel the keyboard eventReply = FEventRouter::RouteAlongFocusPath(this, FEventRouter::FTunnelPolicy(EventPath), InKeyEvent, [] (const FArrangedWidget& CurrentWidget, const FKeyEvent& Event){if (CurrentWidget.Widget->IsEnabled()){const FReply TempReply = CurrentWidget.Widget->OnPreviewKeyDown(CurrentWidget.Geometry, Event);return TempReply;}return FReply::Unhandled();}, ESlateDebuggingInputEvent::PreviewKeyDown);

别看FEventRouter::RouteAlongFocusPath<> 函数不一样 其实也是 FEventRouter::Route <>

5.玩家控制器拿到输入事件

1.玩家控制器的输入事件也是从一个Slate控件传递下来的

只是比我们的UMG创建的SObjectWidget在树中的层级 高了很多

2.玩家控制器只要获取鼠标输入事件他就会进行捕获鼠标 还有焦点
这样的话焦点路径和捕获路径都被设置成当前的Slate控件了 (一般是SViewport类似的)
以后该Slate控件后面的控件都没法拿到输入了

参考:

(6 条消息) UE4-Slate源码学习(二)slate事件触发 - 知乎

虚幻引擎UI组件开发快速入门【UMG/Slate】_umg获取slate-CSDN博客

UE4c++ Slate整套学习流程(源码编译+Slate框架+SlateViewer)_widget reflector-CSDN博客

【UE Slate】 虚幻引擎Slate开发快速入门-CSDN博客
tails/126990479?spm=1001.2014.3001.5506)

【UE Slate】 虚幻引擎Slate开发快速入门-CSDN博客

相关文章:

  • 【 MyBatis-Plus | 精讲 】
  • 1 Studying《Is Parallel Programming Hard》1-5
  • 【网络安全】密码学知识普及
  • leetcode.2014 重复k次的最长子序列
  • Unity 脚本自动添加头部注释
  • 不同信创系统如何集中远程运维?贝锐向日葵提供稳定方案
  • 科技如何影响我们的生活?
  • word中如何保存高清图片,并保存为高质量的pdf文件(图像不失真)
  • uniappx 安卓app项目本地打包运行,腾讯地图报错:‘鉴权失败,请检查你的key‘
  • CSS3实现同心圆效果
  • 系统架构设计师论文分享-论单元测试方法及其应用
  • SolidWorks 镜像实体操作指南:解决镜像失败的常见问题
  • Oracle/PostgreSQL/MSSQL/MySQL函数实现对照表
  • SQL Server for Linux 如何实现高可用架构
  • 多模态融合相机L3CAM
  • 腾讯云TSE注册中心实战:Nacos高可用集群搭建与流量治理避坑指南
  • 如何给程序员用户画像?
  • MySQL 第十一讲---进阶篇 索引(上)
  • 【前端】⭐️通过vite构建项目
  • SQL学习笔记4