見出し画像

UE5から始める C++ & BP 09 【C++版】Enumeration(列挙型)

Blueprint側が出来たし、あっという間に書けるだろう

C++のEnumerationは手ごわかった

C++は自由度があるので、BlueprintのEnumerationはかなり制限されていますね。

まだまだC++で出来ることは深そうです。

それでは、Blueprintの処理をC++で再現します。

【C++版】Enumeration(列挙型)

C++でBlueprintを再現すること

Enumeration(列挙型)をC++で作成します。

Switch文をint32から作成したEnumeration(列挙型)に変更します。

Visual Studioを開いて、編集するファイルを作成する

プロジェクトを閉じていたら、プロジェクトを開き、
「Chapter_2_Enumeration」を開きます。

[Tools]メニューから[New C++ Class]を開きます。

親クラスに[Actor]を選択します。

ClassTypeとClass名を設定します。

Solution Explorerから今回編集する2つのファイルを開きます。

  • CPPFlowControlSwitchEnum.h

  • CPPFlowControlSwitchEnum.cpp

開いたファイルを学習する初期状態に修正します。

CPPFlowControlSwitchEnum.h


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "CPPFlowControlSwitchEnum.generated.h"

UCLASS()
class CPP_BP_API ACPPFlowControlSwitchEnum : public AActor
{
	GENERATED_BODY()
	
protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

private:
	// PrintString関数のDurationに設定する変数
	const float Duration = 10.0f;

	// PrintString関数のTextColorに設定する変数
	const FLinearColor TextColor = FColor(255, 255, 255);

	// 計算用の変数
	int32 CalcVarA = 7;
	int32 CalcVarB = 3;

	// Flow Control用の変数
	bool IsPrintHello = false;
	int32 CalcType = 1;

};

CPPFlowControlSwitchEnum.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "CPPFlowControlSwitchEnum.h"
#include "Kismet/KismetSystemLibrary.h"

// Called when the game starts or when spawned
void ACPPFlowControlSwitchEnum::BeginPlay()
{
	Super::BeginPlay();

	FString Message = "C++ Hello World!";

	if (IsPrintHello)
	{
		// PrintStringノードと同じ処理
		// UKismetSystemLibraryクラスのPrintString関数を呼び出す
		UKismetSystemLibrary::PrintString(this, Message, true, true, TextColor, Duration);
	}
	else
	{
		switch (CalcType)
		{
			case 0:
			{
				// Add(足し算)の処理
				int32 ResultAdd = CalcVarA + CalcVarB;
				FString StrResultAdd = FString::Printf(TEXT("%d"), ResultAdd);
				UKismetSystemLibrary::PrintString(this, StrResultAdd, true, true, FColor::Red, Duration);
				break;
			}
			case 1:
			{
				// Subtract(引き算)の処理
				int32 ResultSubtract = CalcVarA - CalcVarB;
				FString StrResultSubtract = FString::Printf(TEXT("%d"), ResultSubtract);
				UKismetSystemLibrary::PrintString(this, StrResultSubtract, true, true, FColor::Yellow, Duration);
				break;
			}
			case 2:
			{
				// Multiply(掛け算)の処理
				int32 ResultMultiply = CalcVarA * CalcVarB;
				FString StrResultMultiply = FString::Printf(TEXT("%d"), ResultMultiply);
				UKismetSystemLibrary::PrintString(this, StrResultMultiply, true, true, FColor::Green, Duration);
				break;
			}
			default:
			{
				// Divide(割り算)の処理(int > float)
				float ResultDivide = (float)CalcVarA / (float)CalcVarB;
				FString StrResultDivide = FString::Printf(TEXT("%f"), ResultDivide);
				UKismetSystemLibrary::PrintString(this, StrResultDivide, true, true, FColor::Blue, Duration);
			}
		}
	}
}

C++でEnumeration(列挙型)「ECPPCalcType」を作成する

C++でEnumeration(列挙型)を作成します。

[Tools]メニューから[New C++ Class]を開きます。

親クラスに「None」を選択します。

ClassTypeとClass名を設定します。

「CPPCalcType.h」のみ使用するので、「CPPCalcType.cpp」は削除します。
Solution Explorerから「CPPCalcType.cpp」をRemoveします。
Solution ExplorerからRemoveしても、ファイルは残っているので、Explorerから「CPPCalcType.cpp」を削除します。

「CPPCalcType.h」にEnumeration(列挙型)を作成します。

C++のEnumeration(列挙型)の書き方は以下のようになります。

CPPCalcType.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "CPPCalcType.generated.h"

UENUM(BlueprintType)
enum class ECPPCalcType : uint8
{
	Add,
	Subtract,
	Multiply,
	Divide
};

Solution Explorerから編集する2つのファイルを開きます。

  • CPPFlowControlSwitchEnum.h

  • CPPFlowControlSwitchEnum.cpp

「CPPFlowControlSwitchEnum.h」を編集します。

  • include文に「CPPCalcType.h」を追加する

  • 変数[CalcType]のVariableTypeを[int32]から[ECPPCalcType]に変更する。

  • 変数[CalcType]の値をECPPCalcType::Subtractに設定する。

CPPFlowControlSwitchEnum.h


#include "CoreMinimal.h"
#include "CPPCalcType.h" // 追加
#include "CPPFlowControlSwitchEnum.generated.h"


	int32 CalcType = 1;
		↓    
	ECPPCalcType CalcType = ECPPCalcType::Subtract;

Enumeration(列挙型)を使用したswitch文の書き方は以下のようになります。

.cpp

switch (CalcType)
{
    case ECPPCalcType::Add:
    {
        // Add(足し算)の処理
        break;
    }
    case ECPPCalcType::Subtract:
    {
        // Subtract(引き算)の処理
        break;
    }
    case ECPPCalcType::Multiply:
    {
        // Multiply(掛け算)の処理
        break;
    }
    case ECPPCalcType::Divide:
    {
        // Divide(割り算)の処理(int > float)
    }
}

「CPPFlowControlSwitchEnum.cpp」のswitch文を「ECPPCalcType」を使用した書き方に変更します。

CPPFlowControlSwitchEnum.cpp


// Fill out your copyright notice in the Description page of Project Settings.


#include "CPPFlowControlSwitchEnum.h"
#include "Kismet/KismetSystemLibrary.h"

// Called when the game starts or when spawned
void ACPPFlowControlSwitchEnum::BeginPlay()
{
	Super::BeginPlay();

	FString Message = "C++ Hello World!";

	if (IsPrintHello)
	{
		// PrintStringノードと同じ処理
		// UKismetSystemLibraryクラスのPrintString関数を呼び出す
		UKismetSystemLibrary::PrintString(this, Message, true, true, TextColor, Duration);
	}
	else
	{
		switch (CalcType)
		{
			case ECPPCalcType::Add:
			{
				// Add(足し算)の処理
				int32 ResultAdd = CalcVarA + CalcVarB;
				FString StrResultAdd = FString::Printf(TEXT("%d"), ResultAdd);
				UKismetSystemLibrary::PrintString(this, StrResultAdd, true, true, FColor::Red, Duration);
				break;
			}
			case ECPPCalcType::Subtract:
			{
				// Subtract(引き算)の処理
				int32 ResultSubtract = CalcVarA - CalcVarB;
				FString StrResultSubtract = FString::Printf(TEXT("%d"), ResultSubtract);
				UKismetSystemLibrary::PrintString(this, StrResultSubtract, true, true, FColor::Yellow, Duration);
				break;
			}
			case ECPPCalcType::Multiply:
			{
				// Multiply(掛け算)の処理
				int32 ResultMultiply = CalcVarA * CalcVarB;
				FString StrResultMultiply = FString::Printf(TEXT("%d"), ResultMultiply);
				UKismetSystemLibrary::PrintString(this, StrResultMultiply, true, true, FColor::Green, Duration);
				break;
			}
			case ECPPCalcType::Divide:
			{
				// Divide(割り算)の処理(int > float)
				float ResultDivide = (float)CalcVarA / (float)CalcVarB;
				FString StrResultDivide = FString::Printf(TEXT("%f"), ResultDivide);
				UKismetSystemLibrary::PrintString(this, StrResultDivide, true, true, FColor::Blue, Duration);
			}
		}
	}
}

Ctrl + Sでファイルを保存し、Compileを行います。

「CPPFlowControlSwitchEnum」をViewportにDrag&Dropします。
PrintStringの出力結果が分かりづらくなるので、「BP_FlowControl_SwitchEnum」を削除します。

Level Editorの[Play]ボタンをクリックします

変数[CalcType]の値が[ECPPCalcType::Subtract]なので、引き算の出力結果が表示されます。

C++で作成したEnumeration(列挙型)をBlueprintで使用する

C++で作成したEnumeration(列挙型)を使用できます。
C++で作成したEnumeration「ECPPCalcType」をBlueprintで使用します。

「BP_FLowControl_SwitchEnum」を開きます。

VariableTypeにEnumeration「ECPPCalcType」を設定した変数[CPPCalcType]を変数に追加します。

列挙型のDefaultValueですが、列挙定数が足りていない場合はプロジェクトを再起動してください。(UE5 EAしか起こらない?)

追加した変数[CPPCalcType]でSwitchノードを作成してみます。
Bluerpintで作成したEnumeration[ECalcType]と同じOutputの実行ピンが表示されました。

C++で作成したEnumeration(列挙型)のDisplayNameを設定する

SwitchノードのOutputの実行ピンに列挙定数の名前が使われていました。
C++では列挙定数名とは別に「DisplayName」を設定してOutputの実行ピンの名称を変更できます。

CPPCalcType.h


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "CPPCalcType.generated.h"

UENUM(BlueprintType)
enum class ECPPCalcType : uint8
{
	Add       UMETA(DisplayName = "Addition"),
	Subtract  UMETA(DisplayName = "Subtraction"),
	Multiply  UMETA(DisplayName = "Multiplicatation"),
	Divide    UMETA(DisplayName = "Division"),
};

Ctrl + Sでファイルを保存し、Compileを行います。

「CPPCalcType.h」を変更してCompileすると、変数[CPPCalcType]に設定していたVariableTypeが「HOTRELOADED ECPPCalcType 0」というVariableTypeになってしまいます。
VariableTypeを[ECPPCalcType]に再設定します。

Switchノードを再度作成すると、[Switch]ノードの実行ピンの名称がDisplay Nameで設定した名称に変更されています。

すべて保存してC++側は終了です。

C++側の説明は以上になります。
プロジェクトをすべて保存しましょう。

Visual StudioのSolutionもすべて保存しましょう。

まとめ

まだEarry Accessだからか、変な挙動をするのは仕方がない。
EA特有の変な挙動なのか、UE4で同じことをして確認しないといけませんね。
行ったり来たりで少しずつ前に進みましょう。

参照URL

UE4から始めるC++&Blueprint 進捗とロードマップ

Zennで進捗報告を行い、GitHubでロードマップを公開中です。
よかったら覗いてみてください。


この記事が気に入ったらサポートをしてみませんか?