UE5のC++で床を動かすチュートリアル

ゲーム開発

これからUE5のC++を使って、床を動かすアクターを作成する方法を学びましょう。C++の知識がなくても大丈夫です。一緒にコードを見ながら、少しずつ理解を深めていきましょう。

アクターの作成

まずは、新しいアクターを作成します。C++クラスを追加し、親クラスをActorに設定します。今回はMyActorという名前にしました。

MyActor.hの解説

MyActor.hはアクターのヘッダファイルです。クラスの宣言や変数、関数のプロトタイプを定義します。

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "Kismet/KismetSystemLibrary.h" //追加
#include "MyActor.generated.h"
  • 必要なヘッダファイルをインクルードしています。
  • KismetSystemLibrary.hは文字列の出力に使用します。

豆知識:ヘッダファイルのインクルード順序

ヘッダファイルをインクルードする際は、以下の順序に従うことが推奨されています。

  1. "MyActor.generated.h"
  2. モジュールのヘッダファイル(例:CoreMinimal.h)
  3. エンジンのヘッダファイル(例:GameFramework/Actor.h)
  4. プロジェクトのヘッダファイル

この順序に従うことで、ヘッダーファイル間の依存関係を適切に管理できます。

UCLASS()
class DEMO_CPP_API AMyActor : public AActor
{
    GENERATED_BODY()
  • UCLASSマクロを使用して、UE5がこのクラスを認識できるようにします。
  • AMyActorクラスはAActorから継承しています。

豆知識:UCLASSマクロ

UCLASSマクロは、UE5のリフレクションシステムにクラスを登録するために使用されます。このマクロを使用することで、エディタでクラスを認識し、ブループリントで使用できるようになります。UCLASSマクロには、以下のようなオプションを指定できます。

  • BlueprintType:ブループリントで使用可能なクラスであることを示します。
  • Blueprintable:このクラスをブループリントの親クラスとして使用できることを示します。
  • EditInlineNew:このクラスのインスタンスをエディタ内で直接作成できることを示します。
public: 
    // Sets default values for this actor's properties
    AMyActor();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;
  • コンストラクタ、BeginPlayTick関数を宣言しています。
  • これらは後でMyActor.cppで定義します。
    // スタティックメッシュ用の変数
    UPROPERTY(EditAnywhere, Category = "Mesh", BlueprintReadWrite)
    UStaticMeshComponent* Mesh;

    // RotatingMovementComponent用の変数
    UPROPERTY(EditAnywhere, Category = "RotationMovement", BlueprintReadWrite)
    URotatingMovementComponent* Rotating;

    // 回転する角度量の変数
    UPROPERTY(EditAnyWhere, Category = "RotationValue", BlueprintReadWrite)
    FRotator MeshRotationValue;
  • UPROPERTYマクロを使用して、変数をエディタで編集可能にしています。
  • Meshはスタティックメッシュコンポーネントへのポインタです。
  • Rotatingは回転移動コンポーネントへのポインタです。
  • MeshRotationValueは回転角度を保持する変数です。

豆知識:UPROPERTYマクロ

UPROPERTYマクロは、変数をUE5のプロパティシステムに公開するために使用されます。このマクロを使用することで、以下のような機能が利用できます。

  • エディタでプロパティを編集可能にする。
  • ブループリントでプロパティを読み書きできるようにする。
  • プロパティのシリアライズとネットワーク同期を自動化する。
  • プロパティにメタデータを追加する(例:Category、Tooltip)。

MyActor.cppの解説

MyActor.cppMyActorクラスの実装が書かれたファイルです。

#include "MyActor.h"

// Sets default values
AMyActor::AMyActor()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;
  • MyActor.hをインクルードしています。
  • コンストラクタでは、Tick関数を毎フレーム呼び出すように設定しています。
    // StaticMeshComponentの作成
    Mesh = CreateDefaultSubobject<UStaticMeshComponent>("StaticMesh");

    // コンポーネントのアタッチ
    Mesh->SetupAttachment(RootComponent);
  • CreateDefaultSubobject関数を使用して、スタティックメッシュコンポーネントを作成しています。
  • 作成したコンポーネントをルートコンポーネントにアタッチしています。

豆知識:コンポーネント

UE5では、アクターの機能をコンポーネントとして分割し、再利用性を高めています。コンポーネントは、メッシュ、コリジョン、オーディオ、モーションなどの機能を提供します。CreateDefaultSubobject関数を使用して、アクターにコンポーネントを追加することができます。

    // ObjectとしてStaticMeshオブジェクトをロード
    static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/LevelPrototyping/Meshes/SM_Cube.SM_Cube"));

    // キューブアセットのロードに成功した場合
    if (CubeVisualAsset.Succeeded())
    {
        // モデルのセットと位置のセット
        Mesh->SetStaticMesh(CubeVisualAsset.Object);
    }
  • ConstructorHelpers::FObjectFinderを使用して、キューブのスタティックメッシュをロードしています。
  • ロードに成功した場合、SetStaticMesh関数でメッシュをセットしています。

豆知識:アセットのロード

UE5では、ConstructorHelpers::FObjectFinderを使用して、コンストラクタ内でアセットをロードすることができます。この方法は、エディタでアセットを選択してプロパティに割り当てる方法に代わるものです。アセットのパスは、TEXTマクロを使用して指定します。

    // メッシュの大きさを指定
    Mesh->SetRelativeScale3D(FVector(5, 5, 1.5f));

    // RotatingMovementComponentのコンポーネント設定
    Rotating = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("Rotation"));

    // 回転する軸の位置を指定
    Rotating->PivotTranslation = FVector(250, 250, 250);

    // 回転量を設定
    MeshRotationValue = FRotator(100, 200, 0);
}
  • メッシュのスケールを設定しています。
  • 回転移動コンポーネントを作成し、回転軸と回転量を設定しています。

豆知識:FVector、FRotator

UE5では、FVectorは3D空間内の位置や方向を表すために使用されます。FRotatorは3D空間内の回転を表すために使用されます。FVectorXYZの成分を持ち、FRotatorPitchYawRollの成分を持ちます。これらの構造体は、UE5の数学ライブラリであるFMathと組み合わせて使用されることが多いです。

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

    // 回転する軸に回転量を設定
    Rotating->RotationRate = MeshRotationValue;

    // PrintStringノードと同じ処理
        // UKismetSystemLibraryクラスのPrintString関数を呼び出す
    UKismetSystemLibrary::PrintString(this, "C++ Hello World!", true, true, FColor::Cyan, 2.f, TEXT("None"));   
}
  • BeginPlay関数はゲーム開始時に呼び出されます。
  • 回転移動コンポーネントの回転レートを設定しています。
  • UKismetSystemLibrary::PrintString関数を使用して、文字列を出力しています。

豆知識:UKismetSystemLibrary

UKismetSystemLibraryは、ブループリントで使用できる便利な関数を提供するクラスです。PrintString関数は、画面に文字列を出力するために使用されます。この関数は、C++からも呼び出すことができます。他にも、時間の遅延、アクターのスポーン、レベルのロードなどの機能が提供されています。

// Called every frame
void AMyActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}
  • Tick関数は毎フレーム呼び出されます。
  • 今回は特に処理を行っていません。

以上がMyActorクラスの解説です。C++でアクターを作成し、コンポーネントを追加して、プロパティを設定する方法を学びました。

アクターの配置

最後に、作成したMyActorをレベルに配置します。

  1. コンテンツブラウザでMyActorを検索します。
  2. MyActorをレベルにドラッグ&ドロップします。
  3. レベルエディタでアクターを選択し、詳細パネルでプロパティを編集します。
    • 回転量を調整したり、メッシュを変更したりできます。

以上で、UE5のC++で床を動かすチュートリアルは完了です。コードを読んで、少しずつC++に慣れていきましょう。わからないことがあれば、ドキュメントを参照したり、他の人に聞いたりしてください。プログラミングは継続的な学習が大切です。応用にチャレンジしてみてくださいね。

全体コード

MyActor.cpp


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

#include "MyActor.h"

// コンストラクタ:アクターのデフォルト値を設定します。
AMyActor::AMyActor()
{
    // このアクターがTickを毎フレーム呼び出すように設定します。
    // パフォーマンス向上のため、必要ない場合はこれをオフにすることができます。
    PrimaryActorTick.bCanEverTick = true;

    // StaticMeshComponentを作成します。
    // CreateDefaultSubobject関数を使用して、"StaticMesh"という名前のコンポーネントを作成します。
    Mesh = CreateDefaultSubobject<UStaticMeshComponent>("StaticMesh");

    // 作成したStaticMeshComponentをルートコンポーネントにアタッチします。
    // これにより、StaticMeshComponentがアクターの位置とともに移動するようになります。
    Mesh->SetupAttachment(RootComponent);

    // StaticMeshオブジェクトをロードします。
    // ConstructorHelpers::FObjectFinderを使用して、指定されたパスからStaticMeshをロードします。
    static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/LevelPrototyping/Meshes/SM_Cube.SM_Cube"));

    // StaticMeshのロードに成功した場合の処理を行います。
    if (CubeVisualAsset.Succeeded())
    {
        // ロードしたStaticMeshをStaticMeshComponentに設定します。
        Mesh->SetStaticMesh(CubeVisualAsset.Object);

        // StaticMeshComponentの位置を設定します。(今回はコメントアウトされています)
        // Mesh->SetRelativeLocation(FVector(0.0f,0.0f,0.0f));
    }

    // StaticMeshComponentのスケールを設定します。
    // FVectorを使用して、X、Y、Z方向のスケールを指定します。
    Mesh->SetRelativeScale3D(FVector(5, 5, 1.5f));

    // RotatingMovementComponentを作成します。
    // CreateDefaultSubobject関数を使用して、"Rotation"という名前のコンポーネントを作成します。
    Rotating = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("Rotation"));

    // RotatingMovementComponentの回転軸を設定します。
    // FVectorを使用して、回転軸の位置を指定します。
    Rotating->PivotTranslation = FVector(250, 250, 250);

    // アクターの回転量を設定します。
    // FRotatorを使用して、ピッチ、ヨー、ロールの回転量を指定します。
    MeshRotationValue = FRotator(100, 200, 0);
}

// ゲーム開始時またはスポーン時に呼び出されます。
void AMyActor::BeginPlay()
{
    // 親クラスのBeginPlay関数を呼び出します。
    Super::BeginPlay();

    // RotatingMovementComponentの回転速度を設定します。
    // 先ほど設定した回転量をRotationRateに代入します。
    Rotating->RotationRate = MeshRotationValue;

    // PrintString関数を使用して、文字列を画面に出力します。
    // UKismetSystemLibraryクラスのPrintString関数を呼び出し、指定されたパラメータを渡します。
    UKismetSystemLibrary::PrintString(this, "C++ Hello World!", true, true, FColor::Cyan, 2.f, TEXT("None"));

}

// 毎フレーム呼び出されます。
void AMyActor::Tick(float DeltaTime)
{
    // 親クラスのTick関数を呼び出します。
    Super::Tick(DeltaTime);

    // 今回は特に処理を行っていません。
}

MyActor.h


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

#pragma once

// 必要なヘッダファイルをインクルードします
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "Kismet/KismetSystemLibrary.h" // PrintString関数を使用するためにインクルード

#include "MyActor.generated.h"

// MyActorクラスの宣言
UCLASS()
class DEMO_CPP_API AMyActor : public AActor
{
    GENERATED_BODY()

public: 
    // アクターのプロパティのデフォルト値を設定するコンストラクタ
    AMyActor();

protected:
    // ゲーム開始時またはスポーン時に呼び出される関数
    virtual void BeginPlay() override;

public: 
    // 毎フレーム呼び出される関数
    virtual void Tick(float DeltaTime) override;

    // StaticMeshComponentを保持する変数
    // EditAnywhere:エディタ上で編集可能にする
    // Category:エディタ上でのカテゴリを指定
    // BlueprintReadWrite:ブループリントから読み書き可能にする
    UPROPERTY(EditAnywhere, Category = "Mesh", BlueprintReadWrite)
    UStaticMeshComponent* Mesh;

    // RotatingMovementComponentを保持する変数
    // EditAnywhere:エディタ上で編集可能にする
    // Category:エディタ上でのカテゴリを指定
    // BlueprintReadWrite:ブループリントから読み書き可能にする
    UPROPERTY(EditAnywhere, Category = "RotationMovement", BlueprintReadWrite)
    URotatingMovementComponent* Rotating;

    // 回転角度を保持する変数
    // EditAnywhere:エディタ上で編集可能にする
    // Category:エディタ上でのカテゴリを指定
    // BlueprintReadWrite:ブループリントから読み書き可能にする
    UPROPERTY(EditAnywhere, Category = "RotationValue", BlueprintReadWrite)
    FRotator MeshRotationValue;

};

参考サイト

【UE4/UE5】C++初心者向け学習メモ - アルゴンUE4/UE5&アプリ開発日記
C++で作ってみましょう(*'ω'*) 今回はついにC++の説明をしていこうと思います。 一部UE関係ないC++特融のことなども少し紹介します。 今回は作る上で必ず使うであろう関数などを重点的に説明します。 ※C++のすごく細かい知識などは少し省くかもしれません。 ※GASなどの難しいお話は説明しません! ■目次 ・C...
Unreal Engine での Cpp プログラミング | Unreal Engine 5.4 ドキュメンテーション | Epic Developer Community
ゲームプレイ クラスの作成および実装に関するリファレンス ページです。
Unreal Engine における Epic の C++ コーディング規約 | Unreal Engine 5.4 ドキュメンテーション | Epic Developer Community
確立された標準とベストプラクティスを順守して、保守可能なコードを記述します。
Unreal Engine でのデリゲートとラムダ関数 | Unreal Engine 5.4 ドキュメンテーション | Epic Developer Community
C++ オブジェクトでメンバ関数を参照し実行するデータ型

コメント

タイトルとURLをコピーしました