From de492455140271f52261621f85a5ce7748c72d36 Mon Sep 17 00:00:00 2001 From: sigaohe <750831855@qq.com> Date: Tue, 6 Aug 2024 16:26:20 +0800 Subject: [PATCH] new --- .../4.3-EnhancedInput.md" | 99 ++++++++++++++++ .../4.4-EnhancedInput.md" | 106 +++++------------- 2 files changed, 124 insertions(+), 81 deletions(-) create mode 100644 "src/unreal/core[\346\240\270\345\277\203]/4.3-EnhancedInput.md" rename "src/unreal/lyra[\345\244\251\347\247\244\345\272\247]/2-ImproveCommonUI.md" => "src/unreal/core[\346\240\270\345\277\203]/4.4-EnhancedInput.md" (79%) diff --git "a/src/unreal/core[\346\240\270\345\277\203]/4.3-EnhancedInput.md" "b/src/unreal/core[\346\240\270\345\277\203]/4.3-EnhancedInput.md" new file mode 100644 index 00000000..3a06f107 --- /dev/null +++ "b/src/unreal/core[\346\240\270\345\277\203]/4.3-EnhancedInput.md" @@ -0,0 +1,99 @@ +--- +title: c4.3Subsystem|EnhancedInput优先级 +order : 403 +category: + - u++ +--- +### 导读 + + + +食用本文建议先了解什么是增强输入系统![直通车](4.2-EnhancedInput) + + + +## EnhancedInput|Action绑定 + + +前文已经对增强输入系统有了个初步的理解。也知道上下文以及Action如何相辅相成。 + + +```cpp + if (const APlayerController* PC = GetOwningPlayer()) + { + LocalPlayer = PC->GetLocalPlayer(); + if (LocalPlayer) + { + if (UEnhancedInputLocalPlayerSubsystem* Subsystem = LocalPlayer->GetSubsystem()) + { + // 检查是否已经添加了输入映射上下文 + if (!Subsystem->HasMappingContext(InputMappingContext)) + { + Subsystem->AddMappingContext(InputMappingContext, 2); + } + } + } + } + + // 绑定聊天切换动作 + if (UEnhancedInputComponent* EnhancedInputComponent = Cast(GetOwningPlayer()->InputComponent)) + { + if (InputAction_ChatToggle) + { + EnhancedInputComponent->BindAction(InputAction_ChatToggle, ETriggerEvent::Triggered, this, &UChatWidgetBase::HandleChatAction); + } + } +``` +## EnhancedInput|Action解绑 + + +现在我们知道怎么绑定Action,怎么解绑Action? + + + +问得好!目前来看根据句柄解绑的方法比较靠谱。但需要手动获取句柄ID + + +```cpp +if (UEnhancedInputComponent* EnhancedInputComponent = Cast(GetOwningPlayer()->InputComponent)) + { + if (InputAction_ChatTab) + { + int32 PreviousAction = -1; + for (int i = 0; i < EnhancedInputComponent->GetNumActionBindings(); i++) { + + if (EnhancedInputComponent->GetActionBinding(i).ActionDelegate.IsBoundToObject(InputAction_ChatTab)) { + + PreviousAction = EnhancedInputComponent->GetActionBinding(i).GetHandle(); + break; + } + + } + EnhancedInputComponent->RemoveActionBindingForHandle(PreviousAction); + } + } +``` + + +可是我实际运行后发现解绑后依然起作用啊! + + +## EnhancedInput|切换IMC优先级 + + +你这种情况极大概率是因为IMC的优先级导致的,你是不是之前的IMC配置过相同的按键? + + + +没错!我在默认的IMC中配置过相同的按键给Action! + + + +那就没错了,如果多个IMC配置了同个Action到相同的按键时,IMC Priority优先级高的生效,这种情况只需要 Priority降级就行了。 + + + + +```cpp +Subsystem->AddMappingContext(InputMappingContext, 1); +``` \ No newline at end of file diff --git "a/src/unreal/lyra[\345\244\251\347\247\244\345\272\247]/2-ImproveCommonUI.md" "b/src/unreal/core[\346\240\270\345\277\203]/4.4-EnhancedInput.md" similarity index 79% rename from "src/unreal/lyra[\345\244\251\347\247\244\345\272\247]/2-ImproveCommonUI.md" rename to "src/unreal/core[\346\240\270\345\277\203]/4.4-EnhancedInput.md" index d95a8ceb..a7f017f5 100644 --- "a/src/unreal/lyra[\345\244\251\347\247\244\345\272\247]/2-ImproveCommonUI.md" +++ "b/src/unreal/core[\346\240\270\345\277\203]/4.4-EnhancedInput.md" @@ -1,21 +1,16 @@ --- -title: LY2.Inputmode的封装。 -order : 2 +title: c4.4Subsystem|EnhancedInput利用路由显示鼠标 +order : 404 category: - - unreal + - u++ --- -## 导读 - - -官方文档介绍CommonUI虽然提供了InputMode函数:UCommonActivatableWidget::GetDesiredInputConfig却没有给出对应的蓝图节点已经属性操作。 -本章节从Lyra的InputConfig出发,观察理解LyraInputmode实现细节。 - ## 前置条件 >安装插件CommonUI ## 实践 + >日常心血来潮,想给我的游戏菜单背景加一个角色查看功能,即:可以操作UI的同时控制游戏模型(比如旋转、缩放等)。 @@ -172,13 +167,21 @@ enum class EMouseCaptureMode : uint8 例如:我想配置一个全局的输、鼠标交互模式。 - ![](..%2Fassets%2FUCommonInputActionDomain.jpg) +![](..%2Fassets%2FUCommonInputActionDomain.jpg) * Display in ActionBar :简单来说就是对应的按键UI显示在指定的动作栏中。类似下面的效果: - ![](..%2Fassets%2Faction%20bar.jpg) +![](..%2Fassets%2Faction%20bar.jpg) + +使用CommonUI后原本的输入模式就失效了。 + + +![checkout.jpg](..%2Fassets%2Fcheckout.jpg) -## 源码剖析 + +### 源码剖析 + +![](..%2Fassets%2Fcommonuiroot.jpg) `ActivatableWidget.h` @@ -298,81 +301,22 @@ void UExorcistActivatableWidget::ValidateCompiledWidgetTree(const UWidgetTree& B ``` - -打住打住!你管这叫源码剖析? - -## 回顾 +## Route|输入路由子系统 - -很好!我们从头分析!我们先来重新复习一下CommonUI有哪些现成的Widget类 + +上方得知,我们配置的核心其实就是FUIInputConfig,而在CommonUI中可以使用Router子系统来管理配置我们要显示的UI -![](..%2Fassets%2Fcommonuiroot.jpg) - -## 扩展 - -怎么通过蓝图节点进行输入模式的切换设置呢。 - -简单!将 `EditDefaultsOnly` 修改为 `EditAnywhere`,这样就可以在蓝图中任何地方编辑该属性了。就ok了! +> UCommonUIActionRouterBase : public ULocalPlayerSubsystem ```cpp -// ExorcistActivatableWidget.h -protected: - /** 激活此 UI 时要使用的所需输入模式,例如您是否希望按键仍然传递到游戏/玩家控制器? */ - UPROPERTY(EditAnywhere, Category = Input) - EExorcistWidgetInputMode InputConfig = EExorcistWidgetInputMode::Default; // 输入模式 -``` - -### 流程 - -首先,我们在头文件中添加新的声明: - -```cpp -// ExorcistActivatableWidget.h - -#pragma once - -#include "CoreMinimal.h" -#include "UI/ExorcistActivatableWidget.h" -#include "ExorcistBlueprintFunctionLibrary.generated.h" - -/** - * - */ -UCLASS() -class YOURPROJECT_API UExorcistBlueprintFunctionLibrary : public UBlueprintFunctionLibrary -{ - GENERATED_BODY() - -public: - UFUNCTION(BlueprintCallable, Category = "Exorcist") - static void SetExorcistInputMode(UExorcistActivatableWidget* ActivatableWidget, EExorcistWidgetInputMode InputMode); -}; -``` - -现在,你可以在蓝图中调用 `SetInputMode` 来设置输入模式了。 - -同样的:将 `EMouseCaptureMode` 的设置也封装成一个函数,以便在其他地方调用。 - -首先,在 `UExorcistActivatableWidget` 类中添加一个新的函数用于设置鼠标捕获模式: - -```cpp -// ExorcistActivatableWidget.h - -public: - // 设置鼠标捕获模式 - UFUNCTION(BlueprintCallable, Category = "Exorcist") - void SetMouseCaptureMode(EMouseCaptureMode NewCaptureMode); -``` - -在源文件中实现这个函数: - -```cpp -// ExorcistActivatableWidget.cpp - -void UExorcistActivatableWidget::SetMouseCaptureMode(EMouseCaptureMode NewCaptureMode) +if (UCommonUIActionRouterBase* ActionRouter = LocalPlayer->GetSubsystem()) { - GameMouseCaptureMode = NewCaptureMode; + if (bIsChatModeActive) + { + ActionRouter->SetActiveUIInputConfig(FUIInputConfig(ECommonInputMode::Game, EMouseCaptureMode::CapturePermanently)); + UnbindChatTabKey(); + } } ``` \ No newline at end of file