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
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# Lyra中的相关实现
|