提要

本文是对虚幻5新特性插件Enhanced Input的使用学习和代码框架解读,将会从应用和底层两方面对该系统进行分析。

Enhanced Input是对虚幻原生Input系统的拓展,其对输入的处理思路和原Input系统在流程上的思路是一致的。所不同的在于,对一些核心概念进行了提取和抽象,如Action和Action Context。不仅如此,在新框架的加持下,更多的功能特性可以得到发挥,如点触和持续按下等触发操作等。

文章目录

  • 提要
  • 快速使用
    • 准备工作
    • 修改第三人称模板的输入
      • 原第三人称模板的输入配置介绍
      • 使用EnhancedInput调整第三人称模板
  • 总结
  • 参考

快速使用

准备工作

Enhanced Input是以内置插件的形式提供,在Plugins面板,勾选并重启引擎即可激活:

在ContentBrowser里右键,可以看到已经出现了Input相关的新的条目,主要是InputAction资产和InputMapContext资产,说明插件激活成功。

然后需要到项目设置里的Input分栏里,修改默认类的设置:

随后,在代码层面需要在项目的Build.cs文件中添加相应的依赖模块:

public class InsideEnhancedInput : ModuleRules
{public InsideEnhancedInput(ReadOnlyTargetRules Target) : base(Target){...PrivateDependencyModuleNames.AddRange(new string[] {"EnhancedInput"});}
}

这样,不论在Editor里还是项目代码里,我们都可以自由的使用Enhanced Input相关内容了。

修改第三人称模板的输入

原第三人称模板的输入配置介绍

第三人称模板的输入的初识设置主要还是通过在Input->Bindings界面将输入的字符串和按键进行绑定,再在代码/蓝图中为动作(使用字符串)绑定好相应的回调事件。

相应的输入绑定代码:

//
// Inputvoid AInsideEnhancedInputCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{// Set up gameplay key bindingscheck(PlayerInputComponent);PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);PlayerInputComponent->BindAxis("Move Forward / Backward", this, &AInsideEnhancedInputCharacter::MoveForward);PlayerInputComponent->BindAxis("Move Right / Left", this, &AInsideEnhancedInputCharacter::MoveRight);// We have 2 versions of the rotation bindings to handle different kinds of devices differently// "turn" handles devices that provide an absolute delta, such as a mouse.// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystickPlayerInputComponent->BindAxis("Turn Right / Left Mouse", this, &APawn::AddControllerYawInput);PlayerInputComponent->BindAxis("Turn Right / Left Gamepad", this, &AInsideEnhancedInputCharacter::TurnAtRate);PlayerInputComponent->BindAxis("Look Up / Down Mouse", this, &APawn::AddControllerPitchInput);PlayerInputComponent->BindAxis("Look Up / Down Gamepad", this, &AInsideEnhancedInputCharacter::LookUpAtRate);// handle touch devicesPlayerInputComponent->BindTouch(IE_Pressed, this, &AInsideEnhancedInputCharacter::TouchStarted);PlayerInputComponent->BindTouch(IE_Released, this, &AInsideEnhancedInputCharacter::TouchStopped);
}

使用EnhancedInput调整第三人称模板

首先创建输入相关的资产,包括5个InputAction:

  • IA_MoveForward(float)
  • IA_MoveRight(float)
  • IA_Jump(bool)
  • IA_Turn(float)
  • IA_LookUp(float)

IA_MoveForward动作资产配置举例:

再创建1个InputMappingContext,将前面新建的诸多动作资产添加入内(记得对轴对应的按键中的一个作取反Negate操作,否则两个按键将对应同一行为,如MoveForward中对S键取反),并添加相应的按键绑定:

所有资产在ContentBrowser视图下的显示:

代码层面,进入Character类(自定义的继承自Character类),改写其中部分代码:

UCLASS(config=Game)
class AInsideEnhancedInputCharacter : public ACharacter
{...UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category="EnhancedInput")UInputMappingContext* InputMappingContext;UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category="EnhancedInput|Action")UInputAction* IA_MoveForward;UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category="EnhancedInput|Action")UInputAction* IA_MoveRight;UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category="EnhancedInput|Action")UInputAction* IA_Turn;UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category="EnhancedInput|Action")UInputAction* IA_LookUp;UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category="EnhancedInput|Action")UInputAction* IA_Jump;protected:/** Called for forwards/backward input */void MoveForward(const FInputActionValue& Value);/** Called for side to side input */void MoveRight(const FInputActionValue& Value);/** * Called via input to turn at a given rate. * @param Rate  This is a normalized rate, i.e. 1.0 means 100% of desired turn rate*/void TurnAtRate(const FInputActionValue& Value);/*** Called via input to turn look up/down at a given rate. * @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate*/void LookUpAtRate(const FInputActionValue& Value);...
...void AInsideEnhancedInputCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{// 保留原Input系统的输入响应Super::SetupPlayerInputComponent(PlayerInputComponent);if(APlayerController* PC = CastChecked<APlayerController>(GetController())){if(UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer())){Subsystem->AddMappingContext(InputMappingContext, 100);}}if(UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)){if(IA_MoveForward){EnhancedInputComponent->BindAction(IA_MoveForward, ETriggerEvent::Triggered, this, &AInsideEnhancedInputCharacter::MoveForward);}if(IA_MoveRight){EnhancedInputComponent->BindAction(IA_MoveRight, ETriggerEvent::Triggered, this, &AInsideEnhancedInputCharacter::MoveRight);}if(IA_Turn){EnhancedInputComponent->BindAction(IA_Turn, ETriggerEvent::Triggered, this, &AInsideEnhancedInputCharacter::TurnAtRate);}if(IA_LookUp){EnhancedInputComponent->BindAction(IA_LookUp, ETriggerEvent::Triggered, this, &AInsideEnhancedInputCharacter::LookUpAtRate);}if(IA_Jump){EnhancedInputComponent->BindAction(IA_Jump, ETriggerEvent::Started, this, &AInsideEnhancedInputCharacter::Jump);EnhancedInputComponent->BindAction(IA_Jump, ETriggerEvent::Completed, this, &AInsideEnhancedInputCharacter::StopJumping);}}
}...void AInsideEnhancedInputCharacter::TurnAtRate(const FInputActionValue& Value)
{// calculate delta for this frame from the rate informationAddControllerYawInput(Value.GetMagnitude() * TurnRateGamepad * GetWorld()->GetDeltaSeconds());
}void AInsideEnhancedInputCharacter::LookUpAtRate(const FInputActionValue& Value)
{// calculate delta for this frame from the rate informationAddControllerPitchInput(Value.GetMagnitude() * TurnRateGamepad * GetWorld()->GetDeltaSeconds());
}void AInsideEnhancedInputCharacter::MoveForward(const FInputActionValue& Value)
{if ((Controller != nullptr) && (Value.IsNonZero())){// find out which way is forwardconst FRotator Rotation = Controller->GetControlRotation();const FRotator YawRotation(0, Rotation.Yaw, 0);// get forward vectorconst FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);AddMovementInput(Direction, Value.GetMagnitude());}
}void AInsideEnhancedInputCharacter::MoveRight(const FInputActionValue& Value)
{if ( (Controller != nullptr) && (Value.IsNonZero()) ){// find out which way is rightconst FRotator Rotation = Controller->GetControlRotation();const FRotator YawRotation(0, Rotation.Yaw, 0);// get right vector const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);// add movement in that directionAddMovementInput(Direction, Value.GetMagnitude());}
}

这样,编译过后,在相应的Character蓝图界面,可以进行绑定:

最终效果视频:

到这里,我们基本就用EnhancedInput完成了对第三人称模板的改造。

当然还没完,如果只是能够完成之前就已有的工作,那并不能说明这套新玩意的必要性。后面我们来逐渐引入一些不同的特性。

总结

简单总结,在EnhancedInput输入系统的扩展下,我们多了一些可以操作配置的资产,是我们能够实现输入时做一些特别的事情,比如IMC可以让我们配置动作和按键的映射,可以让我们指定哪些输入是生效的;比如IA可以让我们定义一个个的动作;比如Modifier和Trigger可以配置按键生效的条件和生效的效果等等。

普通游戏开发并不需要了解核心代码的部分,掌握其使用已经颇为难得,阅读代码可以进一步加深输入配置、输入响应的流程的理解,但是究其目的本源的话,还是希望以此精进自己对引擎的理解,提升自己的综合能力。

参考

虚幻 5.0 Documentation - Input

虚幻 5.0 Documentation - Lyra Input Settings

知乎作者 Yimi81 的文章《UE5 – EnhancedInput(增强输入系统)》

虚幻中文直播第39期

虚幻5新特性之EnhancedInput相关推荐

  1. 我要学ASP.NET MVC 3.0(一): MVC 3.0 的新特性

    摘要 MVC经过其1.0和2.0版本的发展,现在已经到了3.0的领军时代,随着技术的不断改进,MVC也越来越成熟.使开发也变得简洁人性化艺术化. 园子里有很多大鸟都对MVC了如指掌,面对问题犹同孙悟空 ...

  2. .NET 4.0 Interop新特性ICustomQueryInterface (转载)

    .NET 4.0 Interop新特性ICustomQueryInterface 在.NET Framework v4.0发布的新功能中,在名字空间System.Runtime.InteropServ ...

  3. oracle如何查询虚拟列,Oracle11g新特性之--虚拟列(VirtualColumn)

    Oracle 11g新特性之--虚拟列(Virtual Column) Oracle 11G虚拟列Virtual Column介绍 在老的 Oracle 版本,当我们需要使用表达式或者一些计算公式时, ...

  4. mysql8导入 psc 没有数据_新特性解读 | MySQL 8.0.22 任意格式数据导入

    作者:杨涛涛 资深数据库专家,专研 MySQL 十余年.擅长 MySQL.PostgreSQL.MongoDB 等开源数据库相关的备份恢复.SQL 调优.监控运维.高可用架构设计等.目前任职于爱可生, ...

  5. mysql query browswer_MySQL数据库新特性之存储过程入门教程

    MySQL数据库新特性之存储过程入门教程 在MySQL 5中,终于引入了存储过程这一新特性,这将大大增强MYSQL的数据库处理能力.在本文中将指导读者快速掌握MySQL 5的存储过程的基本知识,带领用 ...

  6. windows无法配置此无线连接_Kubernetes 1.18功能详解:OIDC发现、Windows节点支持,还有哪些新特性值得期待?...

    Kubernetes 1.18发布,一些对社区产生影响的新特性日渐完善,如 KSA(Kubernetes Service Account) tokens的OIDC发现和对Windows节点的支持.在A ...

  7. java字符串去重复_Java 8新特性:字符串去重

    本文首发与InfoQ. 8月19日,Oracle发布了JDK 8u20,JDK 8u20包含很多新特性,比如Java编译器更新.支持在运行时通过API来修改MinHeapFreeRatio和MaxHe ...

  8. Oracle 11g 新特性 -- Transparent Data Encryption (透明数据加密TDE) 增强 说明

    一.TransparentData Encryption (TDE:透明数据加密) 说明 Orace TDE 是Orcle 10R2中的一个新特性,其可以用来加密数据文件里的数据,保护从操作系统层面上 ...

  9. .NET Framework 4.0的新特性

    本文将揭示.NET 4.0中的3个新特性:图表控件.SEO支持以及ASP.NET 4可扩展的输出缓存. 图表控件 微软向开发者提供了大量可免费下载的图表控件,可以在.NET 3.5 ASP.NET或W ...

最新文章

  1. 小蠢笔记:从继承特性来看构造函数
  2. Apache模块开发
  3. SAP里面的ATP的定义
  4. 一种轻量级的C4C业务数据同步到S/4HANA的方式:Odata通知 1
  5. struts2,jsp,freemarker编程小技巧
  6. 对我帮助很大的ESXCLI命令
  7. 用Emmet写前端代码
  8. SSM框架及例子(转)
  9. Balder 3D开发系列之--给自定义基本体进行贴图操作
  10. 【更新】Essential Studio for Xamarin更新至2018 v4(二)
  11. 关于random的多种用法
  12. 选择排序、json对象、indexof、回调函数、ES5新增遍历函数、字符串定义、asc码表、字符串API
  13. 【电子商务安全与支付实验】数字证书的申请及使用
  14. 采用计算机发布调度命令时 必须严格遵守,调度命令规范格式(公文命令).doc...
  15. vue第五天笔记02——vuex数据仓库
  16. CMake入门教程【手册篇】CMake生成与编译项目
  17. 数据结构:网上公开课
  18. Python CSV 转 XLS、XLSX
  19. 什么是readout function/readout函数
  20. Window Internal 读书笔记

热门文章

  1. 求全排列(1) --- dfs 记录
  2. 正交匹配追踪算法OMP(Orthogonal Matching Pursuit)
  3. ArcGIS坡度分析(解决坡度分析80-89°高值居多)
  4. Unity Shader 皮肤水滴效果
  5. 游戏设计模式-单例模式
  6. 一、Ubuntu安装HomebridgeUI
  7. python sample函数取样_Pytorch各种取样器sample
  8. SparkStreaming实时数仓——日活
  9. 特惠快车和快车的区别,滴滴特惠快车老司机说了实话?
  10. 淘淘摘苹果Python版