diff --git a/.obsidian/plugins/various-complements/histories.json b/.obsidian/plugins/various-complements/histories.json index 4bd72fe..4752cc1 100644 --- a/.obsidian/plugins/various-complements/histories.json +++ b/.obsidian/plugins/various-complements/histories.json @@ -1 +1 @@ -{"UBodySetup":{"UBodySetup":{"currentFile":{"count":1,"lastUpdated":1750994347070}}},"Android常用命令":{"Android常用命令":{"internalLink":{"count":1,"lastUpdated":1751942017728}}},"issues":{"issues":{"currentFile":{"count":1,"lastUpdated":1752993735430}}},"TODO清单":{"TODO清单":{"internalLink":{"count":1,"lastUpdated":1753451898745}}},"来Block所有输入。":{"来Block所有输入。":{"currentFile":{"count":1,"lastUpdated":1753454350659}}}} \ No newline at end of file +{"配置IA中的UserSetting选项。":{"配置IA中的UserSetting选项。":{"currentFile":{"count":1,"lastUpdated":1756439877872}}},"AddInputMappings":{"AddInputMappings":{"currentFile":{"count":1,"lastUpdated":1756453435438}}},"AddMappingContext":{"AddMappingContext":{"currentFile":{"count":1,"lastUpdated":1756453441609}}}} \ No newline at end of file diff --git a/03-UnrealEngine/Gameplay/Lyra/UE5 Lyra学习笔记(8)—EnhanceInput(UE5.5).md b/03-UnrealEngine/Gameplay/Lyra/UE5 Lyra学习笔记(8)—EnhanceInput(UE5.5).md index bb302f6..66ad8c6 100644 --- a/03-UnrealEngine/Gameplay/Lyra/UE5 Lyra学习笔记(8)—EnhanceInput(UE5.5).md +++ b/03-UnrealEngine/Gameplay/Lyra/UE5 Lyra学习笔记(8)—EnhanceInput(UE5.5).md @@ -22,7 +22,6 @@ rating: ⭐ - **Input Mapping Contexts**:输入Action的集合。可以为不同GameMode配置不同的 **Input Mapping Contexts**来满足自定义输入的需求。 - **Input Modifiers**: 是一种预处理器,能够修改UE接收的原始输入值,然后再将其发送给输入触发器(Input Trigger)。增强输入插件随附多种输入修饰器,可以执行各种任务,例如更改轴顺序、实现"死区"、将轴输入转换为世界空间。 - **Input Triggers**:用于确定用户输入在经过一系列可选输入修饰器的处理后,是否会激活输入映射上下文中的相应输入动作。 -- **UEnhancedInputUserSettings** (~~PlayerMappableInputConfig~~)**: - 多平台相关:位于Project Settings -> Enhanced Input -> Platform Settings -> Input Data - Mapping Context Redirect:将不同的输入设置用于不同的平台。 - Enhanced Input Platform Data:为你的游戏添加特定于平台的选项。 @@ -119,7 +118,7 @@ ETriggerState UInputTriggerHold::UpdateState_Implementation(const UEnhancedPlaye # Lyra中的相关实现 -ULyraHeroComponent中的输入绑定: +## ULyraHeroComponent中的输入绑定 ```c++ void ULyraHeroComponent::InitializePlayerInput(UInputComponent* PlayerInputComponent) { @@ -146,6 +145,7 @@ void ULyraHeroComponent::InitializePlayerInput(UInputComponent* PlayerInputCompo { if (const ULyraPawnData* PawnData = PawnExtComp->GetPawnData()) { + //获取ULyraInputConfig DataAesset,存储TArray,FLyraInputAction里为InputAction、GameplayTag。 if (const ULyraInputConfig* InputConfig = PawnData->InputConfig) { for (const FInputMappingContextAndPriority& Mapping : DefaultInputMappings) @@ -153,7 +153,8 @@ void ULyraHeroComponent::InitializePlayerInput(UInputComponent* PlayerInputCompo if (UInputMappingContext* IMC = Mapping.InputMapping.Get()) { if (Mapping.bRegisterWithSettings) - { + { + //将IMC注册给UEnhancedInputUserSettings if (UEnhancedInputUserSettings* Settings = Subsystem->GetUserSettings()) { Settings->RegisterInputMappingContext(IMC); @@ -161,7 +162,8 @@ void ULyraHeroComponent::InitializePlayerInput(UInputComponent* PlayerInputCompo FModifyContextOptions Options = {}; Options.bIgnoreAllPressedKeysUntilRelease = false; - // Actually add the config to the local player + // Actually add the config to the local player + //实际添加IMC给LocalPlayer Subsystem->AddMappingContext(IMC, Mapping.Priority, Options); } } @@ -199,4 +201,79 @@ void ULyraHeroComponent::InitializePlayerInput(UInputComponent* PlayerInputCompo UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(const_cast(PC), NAME_BindInputsNow); UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(const_cast(Pawn), NAME_BindInputsNow); } +``` + +# 按键设置与保存 +- [Player Mappable Keys using Enhanced Input](https://dev.epicgames.com/community/learning/tutorials/Vp69/unreal-engine-player-mappable-keys-using-enhanced-input) + +## 相关类 +- **UEnhancedInputUserSettings** (~~PlayerMappableInputConfig~~): 用户输入设置类。通过EnhancedInputLocalPlayerSubsystem->GetEnhancedInputUserSettings()获取。 +- UEnhancedPlayerMappableKeyProfile:一个用户当前设置的实例。比如“默认”与“左撇子"。 + +## 步骤 +1. 假设已经配置好了IMC以及IA。 + 1. 在Controller/Character中注册IMC与IA? + 2. AddMappingContext()的选项OptionsNotifyUserSettings设置为true,会调用UEnhancedInputUserSettings::RegisterInputMappingContext() +2. ProjectSettings - Engine - EnhancedInput - UserSettings中的Enable User Settings +3. 配置IA中的UserSetting选项。 + 1. 1 + +## 加载按键设置逻辑 +默认自动加载,载入逻辑位于UEnhancedInputUserSettings::LoadOrCreateSettings(),调用顺序是: +UEnhancedInputLocalPlayerSubsystem::Initialize +-> +UEnhancedInputLocalPlayerSubsystem::InitalizeUserSettings() +-> +UEnhancedInputUserSettings::LoadOrCreateSettings() + +```c++ +UEnhancedInputUserSettings* UEnhancedInputUserSettings::LoadOrCreateSettings(ULocalPlayer* LocalPlayer) +{ + UEnhancedInputUserSettings* Settings = nullptr; + + if (!LocalPlayer) + { + UE_LOG(LogEnhancedInput, Log, TEXT("Unable to determine an owning Local Player for the given Enhanced Player Input object")); + return nullptr; + } + + // If the save game exists, load it. + if (UGameplayStatics::DoesSaveGameExist(UE::EnhancedInput::SETTINGS_SLOT_NAME, LocalPlayer->GetLocalPlayerIndex())) + { + USaveGame* Slot = UGameplayStatics::LoadGameFromSlot(UE::EnhancedInput::SETTINGS_SLOT_NAME, LocalPlayer->GetLocalPlayerIndex()); + Settings = Cast(Slot); + } + + // If there is no settings save game object, then we can create on + // based on the class type set in the developer settings + const UEnhancedInputDeveloperSettings* DevSettings = GetDefault(); + UClass* SettingsClass = DevSettings->UserSettingsClass ? DevSettings->UserSettingsClass.Get() : UEnhancedInputUserSettings::StaticClass(); + + // This property is marked as "NoClear", so this should be impossible. + if (!ensureMsgf(SettingsClass, TEXT("Invalid Enhanced Input User settings class!"))) + { + return nullptr; + } + + UE_CLOG((Settings && (Settings->GetClass() != SettingsClass)), + LogEnhancedInput, + Log, + TEXT("[%hs] Enhanced Input User Settings class has been changed from '%s' to '%s'. A new settings save object will be created (your saved settings will be reset)"), + __func__, *GetNameSafe(Settings->GetClass()), *GetNameSafe(SettingsClass)); + + // If the settings are null (they dont exist yet) or the class has changed, we need to create a new object. + // The class can change if you modify it in the editor to be something else + if (Settings == nullptr || (Settings->GetClass() != SettingsClass)) + { + Settings = Cast(UGameplayStatics::CreateSaveGameObject(SettingsClass)); + } + + if (ensure(Settings)) + { + Settings->Initialize(LocalPlayer); + Settings->ApplySettings(); + } + + return Settings; +} ``` \ No newline at end of file