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

首先我们需要知道

存储按键信息的是 

UPlayerInput类中的   TMap<FKey,FKeyState> 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行

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

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

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

经过寻找 WM_KEYDOWN  系统消息宏

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

FWindowsApplication::DeferMessage

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

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

ProcessDeferredMessage 函数

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

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

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)

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

最后运行了Lambda函数中的

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

然后到

再到

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

函数

再进入

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

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

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

TargetPlayer->PlayerController

ULocalPlayer::PlayerController 玩家控制器变量

从该变量去调用了 

bool APlayerController::InputKey(const FInputKeyParams& Params)

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

比如这里 我按了M键

在该函数中 

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

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

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

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

至于处理输入的地方是

UPlayerInput中的 ProcessInputStack()虚构函数  

virtual void ProcessInputStack(const TArray<UInputComponent*>& InputComponentStack, const float DeltaTime, const bool bGamePaused);

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

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

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

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

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

总结:

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

这个信息

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

进行储存  

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

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值