首先我们需要知道
存储按键信息的是
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的萌新