まずはBuild設定をいじくろう
しょっぱな嫌な気持ちになる。出鼻をくじかれる。しかしやるしかない。
C++でプロジェクトを新規作成するとIDEが立ち上がる。ファイルツリーの中から
自分が命名したプロジェクト名.Build.csファイルを見つけ開こう。
以下が開いて無編集の状態。
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class HogeProject : ModuleRules
{
public HogeProject(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
なにがなにやら私はわからないが、このコードを以下のように編集すればよいらしい。
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class HogeProject : ModuleRules
{
public HogeProject(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput" }); // ここ!!
PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
"EnhancedInput"と追加しよう。これを追加することでC++でEnhancedInputを扱えるようになるみたいです。
記述したけど動かない!って人は私もそうだった。ビルドし直したり再起動したりなんだりしていたら、直った。
いよいよ実装
まずは.hファイル
// Bulid.csファイルをいじらないとこのincludeでエラーを吐く。
#include "InputMappingContext.h" // 追加
#include "InputAction.h" // 追加
#include "InputActionValue.h" // 追加
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class FOURHIT_API UMyInputComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UMyInputComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
UPROPERTY()
class UInputMappingContext* DefaultMappingContext;
UPROPERTY()
class UInputAction* MyInputAction;
void MyInputPressedAction(const FInputActionValue& Value);
void MyInputReleasedAction(const FInputActionValue& Value);
InputMappingContextとInputActionはエディタで作っている前提です。
まずはそれらを入れる変数、後にイベント関数に登録する関数を宣言する。
続いて.cppファイル
// Bulid.csファイルをいじらないとこのincludeでエラーを吐く。
#include "Kismet/KismetSystemLibrary.h" // 追加
#include "Kismet/GameplayStatics.h" // 追加
#include "Components/InputComponent.h" // 追加
#include "EnhancedInputComponent.h" // 追加
#include "EnhancedInputSubsystems.h" // 追加
UMyInputComponent::UMyInputComponent()
{
PrimaryComponentTick.bCanEverTick = true;
// IA_Actionを読み込み
MyInputAction = LoadObject<UInputAction>(NULL, TEXT("/Game/Input/IA_MyInputAction.IA_MyInputAction"), NULL, LOAD_None, NULL);
// IMCを読み込み
DefaultMappingContext = LoadObject<UInputMappingContext>(NULL, TEXT("/Game/Input/IMC_Default.IMC_Default"), NULL, LOAD_None, NULL);
}
void UFourHitInputComponent::BeginPlay()
{
Super::BeginPlay();
// ...
// PlayerContollerの取得
APlayerController* Controller = UGameplayStatics::GetPlayerController(GetWorld(), 0);
// 入力を有効にする
GetOwner()->EnableInput(Controller);
if (GetOwner()->InputComponent)
{
// InputComponentをUEnhancedInputComponentにCastしている
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(GetOwner()->InputComponent))
{
// Input Actionのイベント関数を登録していると思われる
EnhancedInputComponent->BindAction(MyInputAction, ETriggerEvent::Triggered, this, &UFourHitInputComponent::MyInputPressedAction);
EnhancedInputComponent->BindAction(RowCursorInput, ETriggerEvent::Completed, this, &UFourHitInputComponent::MyInputReleasedAction);
}
// !:if文の条件式内で変数宣言することで変数のスコープを短くできる
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
{
// Input Mapping Contextを登録する
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
}
これで完了。ここまでお疲れ様。