前言
- 在Actor中可以直接在Keyboard Event中選擇相應的鍵盤按鍵觸發事件:
問題背景
- 讀取json數據生成WB(Widget Blueprint)
- 鍵盤快鍵鍵響應事件 == 點擊(On Click)WB事件
- 上面在Actor中可以直接選擇事件,但是我的需求是鍵盤快捷鍵響應 與 WB綁定的On Click事件 等同。
目的
- 將用戶的按鍵輸入事件傳遞到UMG中,在UMG中響應邏輯。
當然也可以選擇有輸入組件能力的角色進行事件傳遞,但這處理起來很麻煩,我們需要角色持有UMG的對象指針,並且需要維護數據對象。
解決思路
- 構建UMG
- 將UMG添加到視口
- 在用戶輸入事件列表中注冊輸入事件
- 在UMG中綁定輸入事件
- 上述思路,個人是通過讀取Json文件循環創建。1~2步驟按照個人需求實現
- 用戶輸入事件注冊:
- Edit——>Project Settings——>Engine——>input
- 右側選擇Action Mappings,添加KeyName和ActionName
- 在項目用戶輸入列表中加入如下輸入事件

- 在UMG中加入如下藍圖內容

- 注意
- UMG中只能響應Action事件,如果需要響應Axis事件需要自行編寫邏輯
- 勾選Consume則事件只傳遞到當前UMG,不會向下傳遞,如果需要向下傳遞,可去掉節點中的勾
- Action Name是在用戶輸入事件列表中注冊的名稱
C++實現
-
UE4提供了UInputKeySelector控件,可以通過鼠標點擊激活快捷鍵輸入,然后點擊鍵盤上按鍵,可以通過將設置的快捷鍵,顯示出來
-
設置快捷鍵的根本思路,通過移除在InputSettings上一個AxisMap或者ActionMap,然后把新的AxisMap或者ActionMap添加進InputSettings
-
關鍵性代碼:
void UI_Option::RebindActionMapping(const FName KeyName, const FKey Key) { if (KeyName.IsValid()) { TArray<struct FInputActionKeyMapping> ActionMappings = UInputSettings::GetInputSettings()->GetActionMappings(); for (int32 ActionIndex = 0; ActionIndex < ActionMappings.Num(); ++ActionIndex) { if (ActionMappings[ActionIndex].ActionName == KeyName) { UInputSettings::GetInputSettings()->RemoveActionMapping(ActionMappings[ActionIndex]); FInputActionKeyMapping ActionMap; ActionMap.ActionName = KeyName; ActionMap.Key = Key; UInputSettings::GetInputSettings()->AddActionMapping(ActionMap); } } } UInputSettings::GetInputSettings()->SaveKeyMappings(); UInputSettings::GetInputSettings()->ForceRebuildKeymaps(); } void UI_Option::RebindAxisMapping(const FName KeyName, const FKey Key) { if (KeyName.IsValid()) { TArray<struct FInputAxisKeyMapping> AxisMappings = UInputSettings::GetInputSettings()->GetAxisMappings(); for (int32 AxisIndex = 0; AxisIndex < AxisMappings.Num(); ++AxisIndex) { if (AxisMappings[AxisIndex].AxisName == KeyName) { UInputSettings::GetInputSettings()->RemoveAxisMapping(AxisMappings[AxisIndex]); FInputAxisKeyMapping AxisMap; AxisMap.AxisName = KeyName; AxisMap.Key = Key; UInputSettings::GetInputSettings()->AddAxisMapping(AxisMap); } } } UInputSettings::GetInputSettings()->SaveKeyMappings(); UInputSettings::GetInputSettings()->ForceRebuildKeymaps(); } -
整體思路
- 先把ue4 項目設置里Input設置的ActionName和AxisName以及他的綁定Key用一種數據結構存儲起來【如果考慮組合鍵也要把組合鍵的關系存起來】
- 在考慮存儲數據結構時,要考慮按鍵【泛指:鍵盤,手柄】不能沖突,所以在重置一個功能的按鍵【L】時首先要把輸入設置中與按鍵【L】相關的設置為無效的(當然,當你檢測到輸入按鍵【L】有其他功能在使用時,也可以彈提示框警告,然后拒絕重置操作,在這里討論直接讓輸入生效,並且使用該快捷鍵的其他功能快捷鍵失效)
- 在考慮數據結構時,需要存儲並更新原來的ActionName或AxisName與key的綁定關系
- 在真正保存應用修改時,執行綁定關系
- 在考慮數據結構時,需要保存修改后的快捷鍵設置狀態,如果把(1)-(4)考慮的數據結構,和保存數據融合在一起,則顯得不夠優雅,並且在使用UGameplayStatics::SaveGameToSlot進行保存時,還需要進行數據處理,因為你沒必要保存重置、更新功能的方法,所以要與保存的數據進行分離,並且要支持多端輸入,保存的最好是一個對應功能Key的數組
- 功能性結構,與保存數據結構如何關聯,增加一個功能如何快速增加快捷鍵;在考慮這個問題時,有兩種方式,一種是函數式,一種是宏;使用宏調試不能正確跳轉,建議使用函數式,當點保存時,把新的值寫進本地,否者,重新讀本地值,重新刷新界面,判定是否更改,可以對比內存值與本地值進行對比;


