UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台

首先我们需要知道

存储按键信息的是 

UPlayerInput类中的   TMap KeyStateMap;  变量

应该是这里  我经过从 Windows窗口中的消息处理函数中

进行追踪

所封的消息函数:

LRESULT CALLBACK FWindowsApplication::AppWndProc(HWND hwnd, uint32 msg, WPARAM wParam, LPARAM lParam)
{
    return WindowsApplication_WndProc( hwnd, msg, wParam, lParam );
}

位置:

EpicGames\UE_5.2\Engine\Source\Runtime\ApplicationCore\Private\Windows\WindowsApplication.cpp   922行

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第1张图片

最终传入 WindowsApplication->ProcessMessage( hwnd, msg, wParam, lParam );

FWindowsApplication::ProcessMessage( HWND hwnd, uint32 msg, WPARAM wParam, LPARAM lParam ) 函数中进行消息处理

而 WindowsApplication 变量 感觉是全局变量 没看到类作用域

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第2张图片

经过寻找 WM_KEYDOWN  系统消息宏

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第3张图片

我们发现 UE是统一进入DeferMessage()函数中进行处理的

FWindowsApplication::DeferMessage

( TSharedPtr& NativeWindow, HWND InHWnd, uint32 InMessage, WPARAM InWParam, LPARAM InLParam, int32 MouseX, int32 MouseY, uint32 RawInputFlags )

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第4张图片

我按一个按键时  进入的是else 分支

ProcessDeferredMessage 函数

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第5张图片

然后进入 MessageHandler->OnKeyDown( ActualKey, CharCode, bIsRepeat )函数

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第6张图片

这是个虚构函数 跳转到此处 

FSlateApplication::OnKeyDown( const int32 KeyCode, const uint32 CharacterCode, const bool IsRepeat ) 

 

后进入FSlateApplication::ProcessKeyDownEvent( const FKeyEvent& InKeyEvent ) 函数中

在该处进入

// Send out key down events.
if ( !Reply.IsEventHandled() )
{
    Reply = FEventRouter::RouteAlongFocusPath(this, FEventRouter::FBubblePolicy(EventPath), InKeyEvent, [] (const FArrangedWidget& SomeWidgetGettingEvent, const FKeyEvent& Event)

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第7张图片

由于是个Lambda函数的回调 该函数返回 FReply 类型 这个语法我还不知道 我只知道一个尾置返回 我们追踪到这个位置使用了Lambda函数 425行

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第8张图片

最后运行了Lambda函数中的

const FReply TempReply = SomeWidgetGettingEvent.Widget->OnKeyDown(SomeWidgetGettingEvent.Geometry, Event);

然后到

再到

FSceneViewport::OnKeyDown( const FGeometry& InGeometry, const FKeyEvent& InKeyEvent )

函数

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第9张图片

再进入

ViewportClient->InputKey(FInputKeyEventArgs(this, InKeyEvent.GetInputDeviceId(), Key, InKeyEvent.IsRepeat() ? IE_Repeat : IE_Pressed, 1.0f, false) 函数

进入了UGameViewportClient::InputKey(const FInputKeyEventArgs& InEventArgs)

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第10张图片

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第11张图片

在664行  我们终于见到了熟悉的东西 

TargetPlayer->PlayerController

ULocalPlayer::PlayerController 玩家控制器变量

从该变量去调用了 

bool APlayerController::InputKey(const FInputKeyParams& Params)

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第12张图片

看这是断点信息  参数传入了一个有按键信息的类型

比如这里 我按了M键

在该函数中 

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第13张图片

这一行 进行了  UPlayerInput::InputKey(const FInputKeyParams& Params) 函数的调用

玩家输入类中在此处进行将 Key 存储 到 KeyStateMap 变量中

我们注意到函数里有很多这样的语句

FKeyState& KeyState = KeyStateMap.FindOrAdd(Params.Key);

UE APlayerController玩家控制器 是如何取得系统所发的系统按下按键信息的?Windows平台_第14张图片

至于处理输入的地方是

UPlayerInput中的 ProcessInputStack()虚构函数  

virtual void ProcessInputStack(const TArray& InputComponentStack, const float DeltaTime, const bool bGamePaused);

当然UPlayerInput 中的ProcessInputStack()函数处理的是UE旧的输入方式  操作映射和轴映射

UE新的增强型输入 所对应的 处理玩家输入类是 UEnhancedPlayerInput

在UEnhancedPlayerInput中有全新的ProcessInputStack 重写的虚函数

virtual void ProcessInputStack(const TArray& InputComponentStack, const float DeltaTime, const bool bGamePaused) override;

来进行处理新的增强型输入逻辑

总结:

按键信息是保存到 UPlayerInput :: KeyStateMap 变量中

这个信息

通过APlayerController :: InputKey 函数调用 UPlayerInput :: InputKey 函数中

进行储存  

有错误请佬们指正  我是个学习UE的萌新

你可能感兴趣的:(学习UE,windows,ue5,c++)