當前位置:網站首頁>虛幻5新特性之EnhancedInput
虛幻5新特性之EnhancedInput
2022-05-14 11:02:16【Athrun_阿斯蘭】
提要
本文是對虛幻5新特性插件Enhanced Input的使用學習和代碼框架解讀,將會從應用和底層兩方面對該系統進行分析。
Enhanced Input是對虛幻原生Input系統的拓展,其對輸入的處理思路和原Input系統在流程上的思路是一致的。所不同的在於,對一些核心概念進行了提取和抽象,如Action和Action Context。不僅如此,在新框架的加持下,更多的功能特性可以得到發揮,如點觸和持續按下等觸發操作等。
快速使用
准備工作
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界面將輸入的字符串和按鍵進行綁定,再在代碼/藍圖中為動作(使用字符串)綁定好相應的回調事件。
相應的輸入綁定代碼:
//
// Input
void AInsideEnhancedInputCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// Set up gameplay key bindings
check(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 joystick
PlayerInputComponent->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 devices
PlayerInputComponent->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 information
AddControllerYawInput(Value.GetMagnitude() * TurnRateGamepad * GetWorld()->GetDeltaSeconds());
}
void AInsideEnhancedInputCharacter::LookUpAtRate(const FInputActionValue& Value)
{
// calculate delta for this frame from the rate information
AddControllerPitchInput(Value.GetMagnitude() * TurnRateGamepad * GetWorld()->GetDeltaSeconds());
}
void AInsideEnhancedInputCharacter::MoveForward(const FInputActionValue& Value)
{
if ((Controller != nullptr) && (Value.IsNonZero()))
{
// find out which way is forward
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get forward vector
const 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 right
const 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 direction
AddMovementInput(Direction, Value.GetMagnitude());
}
}
這樣,編譯過後,在相應的Character藍圖界面,可以進行綁定:
最終效果視頻:
到這裏,我們基本就用EnhancedInput完成了對第三人稱模板的改造。
當然還沒完,如果只是能够完成之前就已有的工作,那並不能說明這套新玩意的必要性。後面我們來逐漸引入一些不同的特性。
總結
簡單總結,在EnhancedInput輸入系統的擴展下,我們多了一些可以操作配置的資產,是我們能够實現輸入時做一些特別的事情,比如IMC可以讓我們配置動作和按鍵的映射,可以讓我們指定哪些輸入是生效的;比如IA可以讓我們定義一個個的動作;比如Modifier和Trigger可以配置按鍵生效的條件和生效的效果等等。
普通遊戲開發並不需要了解核心代碼的部分,掌握其使用已經頗為難得,閱讀代碼可以進一步加深輸入配置、輸入響應的流程的理解,但是究其目的本源的話,還是希望以此精進自己對引擎的理解,提昇自己的綜合能力。
參考
虛幻 5.0 Documentation - Lyra Input Settings
知乎作者 Yimi81 的文章《UE5 – EnhancedInput(增强輸入系統)》
虛幻中文直播第39期
版權聲明
本文為[Athrun_阿斯蘭]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/134/202205141100542127.html
邊欄推薦
- 【服務器數據恢複】硬盤壞道和不穩定扇區導致服務器崩潰的數據恢複案例
- 性能測試報告編寫技巧
- ASP.NET對Cookie的操作方法有哪些
- SAP UI5 應用開發教程之八十七 - 如何讓 SAP UI5 Mock 服務器支持自定義 url 參數試讀版
- Redis基礎之溫故
- 神經網絡中的反向傳播&&參數更新
- 深度學習基礎知識點(一)CNN卷積神經網絡——1.卷積方面的原理
- 從PlatEMO中提取真實PF前沿
- G020-OP-INS-RHEL-02 RedHat OpenStack 發放雲主機(命令行)
- 解决報錯: AttributeError: module ‘distutils‘ has no attribute ‘version‘,親測有效
猜你喜歡
隨機推薦
- c# 獲取枚舉描述的擴展方法
- 應如何認定解除合同通知的效力?
- 遊戲行業實戰案例5:玩家在線分布
- 【LeetCode】Day59-醜數 & 不同的二叉搜索樹
- CTFSHOW MISC入門
- 【國產免費】分布式作業批量處理平臺TASKCTL驗證的不同方式
- 數學建模學習(66):支持向量機 (SVM)案例實戰
- Thanos Sidecar組件
- Meta AI 宣布對人腦和語言處理進行長期研究
- 檢討書範文生成微信小程序工具源碼-支持流量主
- 元組類型(C# 參考)
- PTC:元宇宙引發醫療設備研發重大變革
- 面試題 01.05. 一次編輯 / 劍指 Offer II 041. 滑動窗口的平均值
- 華為機試第十一題:HJ11 數字顛倒
- Pascal VOC2012數據集
- unzip命令
- flink(scala版)學習一之常用的source
- [電路]7-實際電源模型和等效變換
- Go語言type自定義類型哦
- Pytorch和GPU有關操作(CUDA)
- 不均衡樣本集的重采樣
- uni-app技術分享| uni-app轉小程序-實時消息
- SQL中某個字段大於等於且不等於某值該如何寫
- 【Leetcode】442. 數組中重複的數據
- 2022年為什麼降薪也要跳槽?機會比漲薪很重要?
- 工作流結合動態錶單的工作流程
- 為什麼要使用.NET5?.NET5是未來!
- (pycharm)安裝nltk包
- 安裝Apache
- 利用循環輸入輸出數組(簡便易學)利用循環設置函數
- 雲原生時代的搜索服務算力管理
- 證券投資基金的監管
- ArrayList循環删除元素的常見問題及解决方法
- Stack Overflow 上最熱門的 10 個 Kotlin 問題
- 555 定時器的時間計算
- 二叉樹的最近公共祖先
- 模擬卷Leetcode【普通】931. 下降路徑最小和
- C語言 數組(一維數組 · 二維數組)
- NFC之華為AIPASS認證:測試用例簡介
- 622. 設計循環隊列