UE4-快捷鍵-按鍵監聽事件


前言

  • 在Actor中可以直接在Keyboard Event中選擇相應的鍵盤按鍵觸發事件:
    • Actor: 鍵盤響應事件
    • Keyboard Event:

問題背景

  • 讀取json數據生成WB(Widget Blueprint)
  • 鍵盤快鍵鍵響應事件 == 點擊(On Click)WB事件
  • 上面在Actor中可以直接選擇事件,但是我的需求是鍵盤快捷鍵響應 與 WB綁定的On Click事件 等同。

目的

  • 將用戶的按鍵輸入事件傳遞到UMG中,在UMG中響應邏輯。

當然也可以選擇有輸入組件能力的角色進行事件傳遞,但這處理起來很麻煩,我們需要角色持有UMG的對象指針,並且需要維護數據對象。

解決思路

  1. 構建UMG
  2. 將UMG添加到視口
  3. 在用戶輸入事件列表中注冊輸入事件
  4. 在UMG中綁定輸入事件

  • 上述思路,個人是通過讀取Json文件循環創建。1~2步驟按照個人需求實現
  • 用戶輸入事件注冊:
    • Edit——>Project Settings——>Engine——>input
    • 右側選擇Action Mappings,添加KeyName和ActionName
    • 在項目用戶輸入列表中加入如下輸入事件
    • InputEventRegister
  • 在UMG中加入如下藍圖內容
    ListenforInputActionEvent

  • 注意
  • UMG中只能響應Action事件,如果需要響應Axis事件需要自行編寫邏輯
  • 勾選Consume則事件只傳遞到當前UMG,不會向下傳遞,如果需要向下傳遞,可去掉節點中的勾
  • Action Name是在用戶輸入事件列表中注冊的名稱

C++實現

  1. UE4提供了UInputKeySelector控件,可以通過鼠標點擊激活快捷鍵輸入,然后點擊鍵盤上按鍵,可以通過將設置的快捷鍵,顯示出來

  2. 設置快捷鍵的根本思路,通過移除在InputSettings上一個AxisMap或者ActionMap,然后把新的AxisMap或者ActionMap添加進InputSettings

  3. 關鍵性代碼:

        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();
    	
    }
    
    
  4. 整體思路

    • 先把ue4 項目設置里Input設置的ActionName和AxisName以及他的綁定Key用一種數據結構存儲起來【如果考慮組合鍵也要把組合鍵的關系存起來】
    • 在考慮存儲數據結構時,要考慮按鍵【泛指:鍵盤,手柄】不能沖突,所以在重置一個功能的按鍵【L】時首先要把輸入設置中與按鍵【L】相關的設置為無效的(當然,當你檢測到輸入按鍵【L】有其他功能在使用時,也可以彈提示框警告,然后拒絕重置操作,在這里討論直接讓輸入生效,並且使用該快捷鍵的其他功能快捷鍵失效)
    • 在考慮數據結構時,需要存儲並更新原來的ActionName或AxisName與key的綁定關系
    • 在真正保存應用修改時,執行綁定關系
    • 在考慮數據結構時,需要保存修改后的快捷鍵設置狀態,如果把(1)-(4)考慮的數據結構,和保存數據融合在一起,則顯得不夠優雅,並且在使用UGameplayStatics::SaveGameToSlot進行保存時,還需要進行數據處理,因為你沒必要保存重置、更新功能的方法,所以要與保存的數據進行分離,並且要支持多端輸入,保存的最好是一個對應功能Key的數組
    • 功能性結構,與保存數據結構如何關聯,增加一個功能如何快速增加快捷鍵;在考慮這個問題時,有兩種方式,一種是函數式,一種是宏;使用宏調試不能正確跳轉,建議使用函數式,當點保存時,把新的值寫進本地,否者,重新讀本地值,重新刷新界面,判定是否更改,可以對比內存值與本地值進行對比;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM