2025-08-28 11:47:55 +08:00
---
title: Untitled
date: 2025-08-27 17:03:13
excerpt:
tags:
rating: ⭐
---
# 前言
- 官方文档
- [Enhanced Input ](https://dev.epicgames.com/documentation/en-us/unreal-engine/enhanced-input-in-unreal-engine?application_version=5.5 )
- [Using CommonUI With Enhanced Input ](https://dev.epicgames.com/documentation/en-us/unreal-engine/using-commonui-with-enhnaced-input-in-unreal-engine?application_version=5.5 )
- 知乎文章
- [UE5 -- Lyra中的输入模块(Input) ](https://zhuanlan.zhihu.com/p/537949870 )
- [UE5 Lyra的多模态输入和修改灵敏度配置方案 ](https://zhuanlan.zhihu.com/p/30566880169 )
## 调试命令
- showdebug enhancedinput: 会显示你的项目的可用输入动作和轴映射。
- showdebug devices
# 相关类
- **Input Actions**:配置输入动作 => 数据或者状态用的资产。
- **Input Mapping Contexts**: 输入Action的集合。可以为不同GameMode配置不同的 **Input Mapping Contexts**来满足自定义输入的需求。
- **Input Modifiers**: 是一种预处理器, 能够修改UE接收的原始输入值, 然后再将其发送给输入触发器( Input Trigger) 。增强输入插件随附多种输入修饰器, 可以执行各种任务, 例如更改轴顺序、实现"死区"、将轴输入转换为世界空间。
- **Input Triggers**:用于确定用户输入在经过一系列可选输入修饰器的处理后,是否会激活输入映射上下文中的相应输入动作。
- 多平台相关: 位于Project Settings -> Enhanced Input -> Platform Settings -> Input Data
- Mapping Context Redirect: 将不同的输入设置用于不同的平台。
- Enhanced Input Platform Data: 为你的游戏添加特定于平台的选项。
**InputAction**绑定:
```c++
void AFooBar::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
UEnhancedInputComponent* Input = Cast< UEnhancedInputComponent > (PlayerInputComponent);
// 你可以通过更改"ETriggerEvent"枚举值,绑定到此处的任意触发器事件
Input->BindAction(AimingInputAction, ETriggerEvent::Triggered, this, &AFooBar::SomeCallbackFunc);
}
void AFooBar::SomeCallbackFunc(const FInputActionInstance& Instance)
{
// 获取此处所需任意类型的输入动作的值...
FVector VectorValue = Instance.GetValue().Get< FVector > ();
FVector2D 2DAxisValue = Instance.GetValue().Get< FVector2D > ();
float FloatValue = Instance.GetValue().Get< float > ();
bool BoolValue = Instance.GetValue().Get< bool > ();
// 在此处实现你的精彩功能!
}
```
Runtime **InputMappingContext**添加:
```c++
// 将映射上下文公开为头文件中的属性...
UPROPERTY(EditAnywhere, Category="Input")
TSoftObjectPtr< UInputMappingContext > InputMapping;
// 在你的cpp中...
if (ULocalPlayer* LocalPlayer = Cast< ULocalPlayer > (Player))
{
if (UEnhancedInputLocalPlayerSubsystem* InputSystem = LocalPlayer->GetSubsystem< UEnhancedInputLocalPlayerSubsystem > ())
{
if (!InputMapping.IsNull())
{
InputSystem->AddMappingContext(InputMapping.LoadSynchronous(), Priority);
}
}
}
```
**Input Trigger Timed Base** 会检查输入是否已被按住一段时间,如是,则接受该输入并返回 **持续( Ongoing) ** 状态。
```c++
/** UInputTriggerHold
触发器会在输入保持激活状态达到HoldTimeThreshold秒之后触发。
触发器可以选择触发一次或反复触发。
*/
UCLASS(NotBlueprintable, MinimalAPI, meta = (DisplayName = "Hold"))
class UInputTriggerHold final : public UInputTriggerTimedBase
{
GENERATED_BODY()
bool bTriggered = false;
protected:
virtual ETriggerState UpdateState_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue ModifiedValue, float DeltaTime) override;
public:
virtual ETriggerEventsSupported GetSupportedTriggerEvents() const override { return ETriggerEventsSupported::Ongoing; }
// 输入要保持多久才能导致触发?
UPROPERTY(EditAnywhere, Config, BlueprintReadWrite, Category = "Trigger Settings", meta = (ClampMin = "0"))
float HoldTimeThreshold = 1.0f;
// 此触发器应该仅触发一次,还是在满足保持时间阈值之后每帧触发?
UPROPERTY(EditAnywhere, Config, BlueprintReadWrite, Category = "Trigger Settings")
bool bIsOneShot = false;
virtual FString GetDebugState() const override { return HeldDuration ? FString::Printf(TEXT("Hold:%.2f/%.2f"), HeldDuration, HoldTimeThreshold) : FString(); }
};
ETriggerState UInputTriggerHold::UpdateState_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue ModifiedValue, float DeltaTime)
{
// 更新HeldDuration并派生基础状态
ETriggerState State = Super::UpdateState_Implementation(PlayerInput, ModifiedValue, DeltaTime);
// 在HeldDuration达到阈值时触发
bool bIsFirstTrigger = !bTriggered;
bTriggered = HeldDuration >= HoldTimeThreshold;
if (bTriggered)
{
return (bIsFirstTrigger || !bIsOneShot) ? ETriggerState::Triggered : ETriggerState::None;
}
return State;
}
2025-08-28 14:34:12 +08:00
```
2025-08-28 19:01:21 +08:00
# 按键设置
2025-08-28 14:34:12 +08:00
# Lyra中的相关实现
2025-08-28 19:01:21 +08:00
2025-08-29 12:28:51 +08:00
## ULyraHeroComponent中的输入绑定
2025-08-28 19:01:21 +08:00
```c++
void ULyraHeroComponent::InitializePlayerInput(UInputComponent* PlayerInputComponent)
{
check(PlayerInputComponent);
const APawn* Pawn = GetPawn< APawn > ();
if (!Pawn)
{
return;
}
const APlayerController* PC = GetController< APlayerController > ();
check(PC);
const ULyraLocalPlayer* LP = Cast< ULyraLocalPlayer > (PC->GetLocalPlayer());
check(LP);
UEnhancedInputLocalPlayerSubsystem* Subsystem = LP->GetSubsystem< UEnhancedInputLocalPlayerSubsystem > ();
check(Subsystem);
Subsystem->ClearAllMappings();
if (const ULyraPawnExtensionComponent* PawnExtComp = ULyraPawnExtensionComponent::FindPawnExtensionComponent(Pawn))
{
if (const ULyraPawnData* PawnData = PawnExtComp->GetPawnData< ULyraPawnData > ())
{
2025-08-29 12:28:51 +08:00
//获取ULyraInputConfig DataAesset,存储TArray< FLyraInputAction > , FLyraInputAction里为InputAction、GameplayTag。
2025-08-28 19:01:21 +08:00
if (const ULyraInputConfig* InputConfig = PawnData->InputConfig)
{
for (const FInputMappingContextAndPriority& Mapping : DefaultInputMappings)
{
2025-08-29 12:28:51 +08:00
//获取UInputMappingContext并进行注册。
2025-08-28 19:01:21 +08:00
if (UInputMappingContext* IMC = Mapping.InputMapping.Get())
{
if (Mapping.bRegisterWithSettings)
2025-08-29 12:28:51 +08:00
{
2025-08-28 19:01:21 +08:00
if (UEnhancedInputUserSettings* Settings = Subsystem->GetUserSettings())
{
Settings->RegisterInputMappingContext(IMC);
}
FModifyContextOptions Options = {};
Options.bIgnoreAllPressedKeysUntilRelease = false;
// Actually add the config to the local player
Subsystem->AddMappingContext(IMC, Mapping.Priority, Options);
}
}
}
// The Lyra Input Component has some additional functions to map Gameplay Tags to an Input Action.
// If you want this functionality but still want to change your input component class, make it a subclass
// of the ULyraInputComponent or modify this component accordingly.
ULyraInputComponent* LyraIC = Cast< ULyraInputComponent > (PlayerInputComponent);
if (ensureMsgf(LyraIC, TEXT("Unexpected Input Component class! The Gameplay Abilities will not be bound to their inputs. Change the input component to ULyraInputComponent or a subclass of it.")))
{
// Add the key mappings that may have been set by the player
LyraIC->AddInputMappings(InputConfig, Subsystem);
// This is where we actually bind and input action to a gameplay tag, which means that Gameplay Ability Blueprints will
// be triggered directly by these input actions Triggered events.
TArray< uint32 > BindHandles;
LyraIC->BindAbilityActions(InputConfig, this, & ThisClass::Input_AbilityInputTagPressed, & ThisClass::Input_AbilityInputTagReleased, /*out*/ BindHandles);
LyraIC->BindNativeAction(InputConfig, LyraGameplayTags::InputTag_Move, ETriggerEvent::Triggered, this, & ThisClass::Input_Move, /*bLogIfNotFound=*/ false);
LyraIC->BindNativeAction(InputConfig, LyraGameplayTags::InputTag_Look_Mouse, ETriggerEvent::Triggered, this, & ThisClass::Input_LookMouse, /*bLogIfNotFound=*/ false);
LyraIC->BindNativeAction(InputConfig, LyraGameplayTags::InputTag_Look_Stick, ETriggerEvent::Triggered, this, & ThisClass::Input_LookStick, /*bLogIfNotFound=*/ false);
LyraIC->BindNativeAction(InputConfig, LyraGameplayTags::InputTag_Crouch, ETriggerEvent::Triggered, this, & ThisClass::Input_Crouch, /*bLogIfNotFound=*/ false);
LyraIC->BindNativeAction(InputConfig, LyraGameplayTags::InputTag_AutoRun, ETriggerEvent::Triggered, this, & ThisClass::Input_AutoRun, /*bLogIfNotFound=*/ false);
}
}
}
}
if (ensure(!bReadyToBindInputs))
{
bReadyToBindInputs = true;
}
UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(const_cast< APlayerController * > (PC), NAME_BindInputsNow);
UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(const_cast< APawn * > (Pawn), NAME_BindInputsNow);
}
2025-08-29 12:28:51 +08:00
```
# 按键设置与保存
- [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中注册IMC与IA?
2. ProjectSettings - Engine - EnhancedInput - UserSettings中的Enable User Settings
3. 配置IA中的UserSetting选项。
1.