Ue不消耗輸入

1、介紹

我們都知道ue裏面使用輸入時,都是在PlayerController裏面進行獲取,

使用官方的操作映射,軸映射,以及目前最新的增强型輸入

但是我們發現了一個問題 那就是輸入會被消耗

就是儅我鼠標按在一個按鈕上時 你另一個地方接受不到此次的輸入

你會覺得很奇怪,我也覺得很奇怪

現在我們需要一個功能 那就是游戲的全局中 我鼠標點擊一下就會有特效

這該怎麽辦呢 一開始我覺得簡單 推送一個監聽事件 監控這所以輸入就好了

但是似乎有問題 他會被按鈕控件這些給消耗掉輸入 我們猜想他應該第一個接受到輸入才對啊

所以現在我們需要能第一個接受到輸入的地方

ue裏面似乎已經有了

class IInputProcessor 類

2、大致調用流程

ue似乎是在此處集中處理輸入的

我們從

UE_5.0\Engine\Source\Runtime\ApplicationCore\Private\Windows\WindowsApplication.cpp

int32 FWindowsApplication::ProcessDeferredMessage( const FDeferredWindowsMessage& DeferredMessage ) 函數開始看起

我們就看按鍵按下時 2218行

MessageHandler->OnMouseDown( CurrentNativeEventWindowPtr, MouseButton, CursorPos );

请添加图片描述

MessageHandler 是FGenericApplicationMessageHandler類型的 一個 共享指針

请添加图片描述

FGenericApplicationMessageHandler 内部基本都是虛函數 一看是虛函數我們就應該知道 他主要是看子類來實現的了

请添加图片描述

FSlateApplication 類是一個繼承自 FGenericApplicationMessageHandler

Slate ue自己封裝的一個UI框架(大概 我不是很懂 我目前只是做筆記狀態

请添加图片描述

我們看到他將OnMouseDown虛函數重寫了

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

我們看到這裏繼續傳遞 還傳遞了一個Lambda函數 使用參數類型為

IInputProcessor 進行調用 IInputProcessor::HandleMouseButtonDownEvent在这里插入图片描述

在这里插入图片描述

這裏我們注意到了 調用返回了一個返回值 bool 類型

為true就跳出 不再往下循環調用的 IInputProcessor 的事件了

這裏意味著什麽呢?我們只要能將我們自己IInputProcessor類加入 InputPreProcessorList 中 我們就有機會是第一時間處理輸入的

最後也是返回這個 返回值

在这里插入图片描述

我們的 IInputProcessor
在这里插入图片描述

好了現在我們需要看看調用最初的位置了

在这里插入图片描述

假如我們這裏返回true了就跳出了 不在向下執行了

我們看看下面是什麽

在这里插入图片描述

我們似乎看到了一個眼熟的東西

InMouseCaptorWidget.Widget->OnPreviewMouseButtonDown(InMouseCaptorWidget.Geometry, Event);

OnPreviewMouseButtonDown函數

我們似乎在UserWidget裏面也看到過

在这里插入图片描述

但是這裏的這個是 SWidget裏面的

在这里插入图片描述

是個虛函數 所以現在我們要有一個猜想 UserWidget是否是繼承這個SWidget的?

很可惜並沒有

但是我找到了另一個東西

SObjectWidget 有繼承 SWidget 且重寫了這個函數

在这里插入图片描述

WidgetObject

在这里插入图片描述

看到了是什麽呢? 是UserWidget !!!在这里插入图片描述

我們找到了

現在看到他傳遞過來了

所以我們在 IInputProcessor 中處理輸入一定比UI快一步拿到

在这里插入图片描述

在这里插入图片描述

我們看到鼠標點擊和觸摸點擊是同時處理的

在这里插入图片描述

在这里插入图片描述

流程大概我也只會這裏了

3、使用自己定義的 IInputProcessor 進行處理輸入

首先先定義一個繼承 IInputProcessor 類的類型 FInputHelp_Ysp

在这里插入图片描述

然後將所以 IInputProcessor 中 的虛函數全部重寫 且全返回為false

爲何返回false? 看這裏 爲了不住儅向下處理

在这里插入图片描述

比如我們想處理鼠標按鍵事件

首先我們使用DECLARE_DELEGATE_OneParam 宏 靜態單播代理

DECLARE_DELEGATE_OneParam(FOnInputProcessorMouseButtonEvent, const FPointerEvent&);

在这里插入图片描述

`bool FInputHelp_Ysp::HandleMouseButtonDownEvent(FSlateApplication& SlateApp, const FPointerEvent& MouseEvent)
{
    OnInputMouseButtonEvent.ExecuteIfBound(MouseEvent);

    GEngine->AddOnScreenDebugMessage(-1, 2, FColor::Blue, MouseEvent.GetEffectingButton().ToString());

    return false;
}`

ok 這樣這個類就寫完了

現在我們造一個 **APlayerController **類

ASMPlayerController類

在这里插入图片描述

`void ASMPlayerController::BeginPlay()
{
	Super::BeginPlay();

    InputHelp = MakeShareable(new FInputHelp_Ysp());

    //注册输入
	if (InputHelp)
	{
		FSlateApplication::Get().RegisterInputPreProcessor(InputHelp);
		FPointerEvent MouseEvent;

    //绑定鼠标或触摸按下/抬起
		InputHelp->OnInputMouseButtonEvent.BindLambda(//this,
			[this](const FPointerEvent& MouseEvent)
			{
				GEngine->AddOnScreenDebugMessage(-1, 2, FColor::Red, MouseEvent.GetEffectingButton().ToString());
				this->MouseBottonEvent(MouseEvent);

    }
		);//	BindUObject(this, &ASMPlayerController::MouseBottonEvent);

    //绑定鼠标/触摸 移动
		InputHelp->OnInputMouseMoveEvent.BindLambda(
			[this](const FPointerEvent& MouseEvent)
			{
				GEngine->AddOnScreenDebugMessage(-1, 2, FColor::Red, MouseEvent.GetScreenSpacePosition().ToString());
				this->MouseMoveEvent(MouseEvent);
			}
		);

    }
}`

在这里插入图片描述

在这里插入图片描述

*MakeShareable **函數幹嘛的呢?

說是一個共享指針包裝器

可以容納一個對象的指針

TSharedPtr<FInputHelp_Ysp> InputHelp;

總得來説就是爲了將普通轉換成共享指針的

我們還需要取消注冊

在这里插入图片描述

在这里插入图片描述

你們可能好奇我爲什麽不使用動態單播

因爲我寫的那個 **FInputHelp_Ysp **用不了

我猜想應該是我沒有使用到反射 ue 有個反射頭文件 不太清楚 也可能是沒有繼承UObject

4、藍圖方面

在这里插入图片描述

在这里插入图片描述

在重寫函數裏面找到我們所寫的 MosueBottonEvent 函數

然後從中處理邏輯就好

比如跟隨鼠標 移動一張圖片

在这里插入图片描述

好了述説解釋
個反射頭文件 不太清楚 也可能是沒有繼承UObject
好了述説結束

知乎大佬
UE4 C++ 不吞噬的输入监听
【UE·底层篇】Slate源码分析——点击事件的触发流程梳理(https://zhuanlan.zhihu.com/p/448050955)

  • 11
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值