ゲーム開発
Unity
UnrealEngine
C++
Blender
Houdini
ゲーム数学
ゲームAI
グラフィックス
サウンド
アニメーション
GBDK
制作日記
IT関連
ツール開発
フロントエンド関連
サーバサイド関連
WordPress関連
ソフトウェア設計
おすすめ技術書
音楽
DTM
楽器・機材
ピアノ
ラーメン日記
四コマ漫画
その他
おすすめアイテム
おもしろコラム
  • ゲーム開発
    • Unity
    • UnrealEngine
    • C++
    • Blender
    • Houdini
    • ゲーム数学
    • ゲームAI
    • グラフィックス
    • サウンド
    • アニメーション
    • GBDK
    • 制作日記
  • IT関連
    • ツール開発
    • フロントエンド関連
    • サーバサイド関連
    • WordPress関連
    • ソフトウェア設計
    • おすすめ技術書
  • 音楽
    • DTM
    • 楽器・機材
    • ピアノ
  • ラーメン日記
    • 四コマ漫画
      • その他
        • おすすめアイテム
        • おもしろコラム
      1. ホーム
      2. 20240519_01_ue5_cpp_basic

      【UE5】第一回 ミニゲーム制作で学ぶUnrealC++ 〜UnrealC++の概要 編〜

      UnrealEngineC++制作日記ミニゲームUE5
      2024-05-18

      マイケル
      マイケル
      みなさんこんにちは! マイケルです!
      エレキベア
      エレキベア
      こんにちクマ〜〜〜
      マイケル
      マイケル
      これまでUnity記事をメインに執筆してきましたが、 ついに仕事の関係上UnrealEngineの学習を行っておりました...。
      エレキベア
      エレキベア
      まあどこかで触るだろうとは思っていたクマが・・・
      マイケル
      マイケル
      というわけで、今回から学習も兼ねてUnrealEngine5でのミニゲーム制作について紹介していきます! ブループリントでなくC++メインで開発したゲームとなっていて、「ミニゲームの制作過程を通してUnrealC++で開発する際の方法をざっくり知ろう」という趣旨になっております。
      エレキベア
      エレキベア
      UEはブループリントの情報ばかりで、C++で開発した適度なサンプルが無いのが悩みどころクマね・・・
      マイケル
      マイケル
      今回の記事とサンプルが、これからUnrealEngineのC++開発を学習する方の役に立ってくれれば幸いです・・・。 実際に作ったゲームは猫のエンドレスランゲームで、プレイ動画は下記になります!
      エレキベア
      エレキベア
      おお〜〜ちゃんとゲームになってるクマ
      マイケル
      マイケル
      画面遷移やUI・スコア表示など、ゲームでよく使う機能をなるべく入れたサンプルとなっています。 作成したプロジェクトは下記のGitHubリポジトリにあげているので、こちらも合わせてご参照ください!

      ▼GitHubリポジトリ
      GitHub - plasmo310 / ue5-cat-runner

      ▼UnrealEngineバージョン
      5.3.2

      エレキベア
      エレキベア
      これくらいの量なら把握もしやすいクマね
      マイケル
      マイケル
      今回は第一回ということで作ったゲームの中身には触れずに、UnrealEngineでのC++開発を行う上での基礎知識について紹介していきます!
      エレキベア
      エレキベア
      楽しみクマ〜〜〜

      参考書籍

      マイケル
      マイケル
      今回実装・情報整理するにあたり、下記書籍を参考にさせていただきました!

      C++でつくるUnreal Engineアプリ開発 for Windows & ...

      Unreal Engine 5で極めるゲーム開発:サンプルデータと動画で学ぶゲー...

      マイケル
      マイケル
      C++でつくるUnreal Engineアプリ開発は、UE4の情報にはなりますが数少ないC++について触れられた書籍です。 Unreal Engine 5で極めるゲーム開発は通称極め本と呼ばれていて、業界内では定番書籍として扱われています。 量はありますが、一度見ておいて損はないと思います!
      エレキベア
      エレキベア
      極め本はUE4版もあったクマが、UE5になってまたボリュームが大きくなったクマね

      アクタを作ってみる

      マイケル
      マイケル
      UnrealC++の細かい話に入っていく前に、 まずはとりあえず簡単なコードを書いてみます!
      エレキベア
      エレキベア
      雰囲気をつかむクマね

      ThirdPersonテンプレートで作成

      マイケル
      マイケル
      UnrealEngineのテンプレートは複数ありますが、ここではThirdPersonテンプレートを使用してプロジェクトを作成します。
      20240519_01_ue5_cpp_basic_02
      ▲ThirdPersonテンプレートからC++プロジェクトを作成

      マイケル
      マイケル
      こちらのテンプレートは基本的な移動処理やカメラなども設定されており、3Dゲームの開発が始めやすいものになっています。
      20240519_01_ue5_cpp_basic_03
      ▲作成直後でキャラクターを動かせる

      20240519_01_ue5_cpp_basic_04
      ▲移動処理やカメラも設定されている

      エレキベア
      エレキベア
      定番のテンプレートクマね

      CubeアクタのBPを作成

      マイケル
      マイケル
      そして「BP_Cube」という名称でActorを親としたブループリントを作成し、 こちらに対してCubeオブジェクトを追加しておきます。
      20240519_01_ue5_cpp_basic_06
      ▲ActorのBlueprintを作成

      20240519_01_ue5_cpp_basic_07
      ▲Cubeを追加

      エレキベア
      エレキベア
      Unityでいうプレハブ的な感じクマね
      マイケル
      マイケル
      今回はこちらのCubeが自動で前進するよう、C++のコードを書いてみます。

      Actorクラスを作成

      マイケル
      マイケル
      「CubeActor」という名称でAActorクラスを親としたクラスを作成します。 Public/Privateという指定もありますが、こちらは他モジュールへの公開設定になっています。 独自のモジュールを作成するなどしていない限りは、基本的にPrivateを選択して問題ないです。
      20240519_01_ue5_cpp_basic_05
      ▲「CubeActor」という名称でプライベートクラスを作成

      マイケル
      マイケル
      初期生成されたコードは下記のようになっています。 BeginPlay、Tick関数がそれぞれ開始/更新でゲームループ処理となっています。
      // Fill out your copyright notice in the Description page of Project Settings.
      
      #pragma once
      
      #include "CoreMinimal.h"
      #include "GameFramework/Actor.h"
      #include "CubeActor.generated.h"
      
      UCLASS()
      class ACubeActor : public AActor
      {
      	GENERATED_BODY()
      	
      public:	
      	// Sets default values for this actor's properties
      	ACubeActor();
      
      protected:
      	// Called when the game starts or when spawned
      	virtual void BeginPlay() override;
      
      public:	
      	// Called every frame
      	virtual void Tick(float DeltaTime) override;
      
      };
      
      
      ▲初期生成コード(ヘッダ)
      // Fill out your copyright notice in the Description page of Project Settings.
      
      
      #include "CubeActor.h"
      
      // Sets default values
      ACubeActor::ACubeActor()
      {
       	// 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;
      
      }
      
      // Called when the game starts or when spawned
      void ACubeActor::BeginPlay()
      {
      	Super::BeginPlay();
      	
      }
      
      // Called every frame
      void ACubeActor::Tick(float DeltaTime)
      {
      	Super::Tick(DeltaTime);
      
      }
      
      
      ▲初期生成コード(実装)
      エレキベア
      エレキベア
      AActorはUnityでいうMonoBehaviour的なクラスになっているクマね
      マイケル
      マイケル
      こちらのクラスに対して、「MoveSpeed」という名称で移動スピードの変数を追加し、Tick関数内に移動処理を実装してみます。
      // Fill out your copyright notice in the Description page of Project Settings.
      
      #pragma once
      
      #include "CoreMinimal.h"
      #include "GameFramework/Actor.h"
      #include "CubeActor.generated.h"
      
      UCLASS()
      class ACubeActor : public AActor
      {
      	GENERATED_BODY()
      	
      public:	
      	ACubeActor();
      	virtual void Tick(float DeltaTime) override;
      
      private:
      	/** move forward speed */
      	UPROPERTY(EditAnywhere)
      	float MoveSpeed = 5.0f;
      
      };
      
      
      ▲移動スピードのプロパティを追加
      // Fill out your copyright notice in the Description page of Project Settings.
      
      
      #include "CubeActor.h"
      
      ACubeActor::ACubeActor()
      {
      	PrimaryActorTick.bCanEverTick = true;
      }
      
      void ACubeActor::Tick(float DeltaTime)
      {
      	Super::Tick(DeltaTime);
      
      	// move forward.
      	FVector CurrentLocation = GetActorLocation();
      	CurrentLocation += MoveSpeed * GetActorForwardVector();
      	SetActorLocation(CurrentLocation);
      }
      
      
      ▲Tick関数内で前進させる
      エレキベア
      エレキベア
      UPROPERTYがUnityでいうSerializedFieldみたいな感じクマか

      BPの親クラスに設定

      マイケル
      マイケル
      あとはCubeのブループリント画面 > クラス設定から親クラスを作成したクラスに変更します。 変更後にコンパイルすると、コードに追加したMoveSpeed変数がプロパティとして表示されると思います。
      20240519_01_ue5_cpp_basic_08
      ▲クラス設定から親クラスを変更

      20240519_01_ue5_cpp_basic_09
      ▲追加したプロパティも表示されるようになっている

      エレキベア
      エレキベア
      ブループリントとの紐付けはクラス設定から行うのクマね

      レベルに配置して確認

      マイケル
      マイケル
      最後に、Cubeのブループリントをレベル上に配置します。 ゲームを開始すると前進するのが確認できるかと思います!
      20240519_01_ue5_cpp_basic_10
      ▲BPをレベル上に配置

      20240519_01_ue5_cpp_basic_11
      ▲ゲームを開始すると前進することが確認できる

      エレキベア
      エレキベア
      やったクマ〜〜〜 なんというかUnityと似たような感じで実装できるのクマね

      UnrealC++の概要

      マイケル
      マイケル
      UnrealEngineでのC++開発のイメージが分かったところで、少し踏み込んで概要をまとめてみます。

      UnrealEngineオブジェクトの構成

      マイケル
      マイケル
      まずUnrealEngineでの世界の構成についてですが、下記のように ワールド - レベル - アクタ - コンポーネント の含合関係になっています。
      20240519_01_ue5_cpp_basic_01
      ▲UnrealEngineオブジェクトの構成

      参考:
      UObjectの原理 - RootSetから全て繋がっている
      UnrealEngineドキュメント - UWorld

      • UWorld
        • トップレベルのオブジェクト
        • スタンドアロンゲームでは通常1つのワールドが存在する
      • ULevel
        • 複数のアクタを持つ、Unityでいうシーン的存在
        • レベルの中でもパーシスタントレベルとその中に含むサブレベルがある
      エレキベア
      エレキベア
      なるほどクマ・・・ レベルがUnityでいうSceneにあたるのクマね
      20240519_01_ue5_cpp_basic_12
      ▲レベルの中にアクタを含む形式となる

      アクタとオブジェクト

      マイケル
      マイケル
      そしてアクタ(AActor)の他によく使用するクラスとしてUObjectがあります。 アクタ自身もUObjectを継承していて、UEでの全てのオブジェクトの基本クラスとなっています。
      • AActor
        • ワールドに配置可能な全てのゲームプレイオブジェクト
        • ゲームループによる処理が可能(BeginPlay、Tick)
      • UObject
        • アクタを含め、UnrealEngine全てのオブジェクトの基本クラス

      参考:
      UnrealEngineドキュメント - UnrealArchitecture

      エレキベア
      エレキベア
      ワールドに配置できるのがアクタ全ての基本クラスがUObjectクマね
      マイケル
      マイケル
      その他、よく使用するクラスとしては下記のようなものがあります。 クラス名の頭には接頭辞を付与するルールになっていて、「A」「U」といった文字でどのクラスを継承しているかが判断できるようになっています。
      その他主要クラス
      クラス
      概要
      APawn
      入力を受け取ることができるアクタ(プレイヤー)
      ACharacter
      人間の形をしたPawnで、CapsuleComponent、CharacterMovementComponentがデフォルトで付いている
      APlayerCharacter
      Pawnを操作するためのインタフェース
      AGameMode
      ゲームルールや勝敗条件などを含めたゲームの定義
      ALevelScriptActor
      レベルを管理するためのクラス
      UUserWidget
      UMG(UIシステム)にてWidgetの親となるクラス
      マイケル
      マイケル
      このようなアクタやUObjectを生成したり、取得する処理は下記のようになります。 それぞれ用意された関数経由で処理を行うことで、後述するガベージコレクションの仕組みに乗せることができます。
      // Componentの追加(コンストラクタ内にて)
      CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
       
      // UObjectの生成
      HitDetectManager = NewObject<UHitDetectManager>();
       
      // アクタのSpawn
      StageFloor = World->SpawnActor<AStageFloor>(StageFloorActor, SpawnLocation, SpawnRotator, SpawnParams);
       
      // プレイヤー取得
      APawn* PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
      const auto PlayerCharacter = Cast<ACatCharacter>(PlayerPawn);
      if (PlayerCharacter != nullptr)
      {
      ...
      }
       
      // 特定のアクタ取得
      const auto LevelScriptActor = UGameplayStatics::GetActorOfClass(Player->GetWorld(), ARunGameLevelScript::StaticClass());
      const auto RunGameLevelScript = Cast<ARunGameLevelScript>(LevelScriptActor);
      if (RunGameLevelScript != nullptr)
      {
      ...
      }
      
      ▲よく使うオブジェクト操作処理
      エレキベア
      エレキベア
      プレイヤーなんかは専用の取得処理が付いているのクマね

      コンポーネント

      マイケル
      マイケル
      アクタが保有するコンポーネントにも大きく2つの種類があり、トランスフォームを含むSceneコンポーネントと含まないActorコンポーネントがあります。
      • Actorコンポーネント
        • トランスフォームを含まないコンポーネント
      • Sceneコンポーネント
        • トランスフォームを含むコンポーネント

      参考:
      UnrealEngineドキュメント - Component

      20240519_01_ue5_cpp_basic_13
      ▲アクタはコンポーネントを保有できる

      エレキベア
      エレキベア
      コンポーネントもこれらのクラスを継承して作成するクマね

      UPROPERTYとガベージコレクション

      マイケル
      マイケル
      次によく使用するのは「UPROPERTY」の指定です。 これにはガベージコレクションの仕組みも関係するため、まずはそこから触れていきます。
      UEのガベージコレクション
      マイケル
      マイケル
      UnrealEngineのガベージコレクションは、先ほど紹介したオブジェクト構成をたどりながら不要になったUObjectを破棄する仕組みになっています。 そのため、標準C++で記載したクラスを作成しない限りは基本的にメモリ管理は任せることができます。

      UEのガベージコレクションの仕組み

      • ルートセットから辿って不要になった(参照が無くなった)UObjectを破棄する
      • アクタはDestroy関数を呼び出すことで明示的にマーク付けできる
      • ガベージコレクションの頻度等もプロジェクト設定から変更することができる
      エレキベア
      エレキベア
      不要になったかどうかは参照されているかどうかで判断するクマね
      UPROPERTY
      マイケル
      マイケル
      そしてUPROPERTYについてですが、基本的には下記のようにエディタやブループリントに公開したい変数に対して付与する指定になっています。
      	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
      	TObjectPtr<UCameraComponent> FollowCamera;
      
      ▲UPROPERTYの指定
      マイケル
      マイケル
      UnityのSerializedFieldに近いものになっていますが、注意点として参照カウンタ的な役割も担っていることがあります。 UObjectに対してUPROPERTYを付与していないと、意図しないタイミングで破棄されたりなどガベージコレクション関連の不具合に繋がる可能性があるためご注意ください。
      • 基本はレベルエディタやBlueprintに公開するための指定
      • Unityでいう単なるSerializedFieldではなく、参照カウンタとしての役割も担っている
        • キーワードを指定せずに UPROPERTY() を付与することにも意味がある
        • UEオブジェクトの変数には付与しておかないと、GCされない・もしくは勝手に破棄されるといった不具合に繋がるため注意

      参考:
      UnrealEngineドキュメント - Optimizations
      UObjectの原理 - docswell

      	UPROPERTY()
      	TObjectPtr<UAudioService> AudioService;
      
      ▲引数無しのUPROPERTYにも意味がある
      エレキベア
      エレキベア
      エディタ等に公開しない場合にも付けないといけないのクマね
      マイケル
      マイケル
      UPROPERTYに指定するキーワードとして、よく使用するレベルエディタ/ブループリントへの公開設定は下記があります。 その他にも指定できるものが多々あるので、この辺りは公式ドキュメントをご参照ください!
      よく使うキーワード
      キーワード
      概要
      VisibleAnywhere
      レベルエディタやBlueprint上で閲覧できる
      EditAnywhere
      レベルエディタから閲覧・編集できる
      BlueprintReadWrite
      Blueprintから閲覧・編集できる
      BlueprintReadOnly
      Blueprintから閲覧できる

      UnrealEngineドキュメント - Optimizations

      エレキベア
      エレキベア
      UPROPERTYが段々分かってきたクマ〜〜〜

      デリゲート

      マイケル
      マイケル
      デリゲートには シングルキャスト or マルチキャストで選べる他、動的 or 静的からも選択できます。 動的デリゲートはシリアライズ可能で、Blueprintから参照することができるその分動作は遅くなるため、C++のみで使用する場合には静的デリゲートの選択を検討しましょう。

      参考:
      UnrealEngineドキュメント - デリゲート

      DECLARE_MULTICAST_DELEGATE...
      DECLARE_DYNAMIC_DELEGATE...
      DECLARE_DYNAMIC_MULTICAST_DELEGATE...
      DECLARE_DYNAMIC_DELEGATE...
      DECLARE_DYNAMIC_MULTICAST_DELEGATE...
      
      ▲決められたマクロを変数に付与することで使用できる
      	/** アクタ衝突時のイベント */
      	DECLARE_DELEGATE_TwoParams(FHitActorDelegate, ACatCharacter*, AActor*);
      	FHitActorDelegate OnHitActorDelegate;
      
      ▲静的シングルデリゲートの例(引数2つ)
      void ACatCharacter::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
      	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
      {
      	// イベント発行
      	if (OnHitActorDelegate.IsBound())
      	{
      		OnHitActorDelegate.Execute(this, OtherActor);
      	}
      }
      
      ▲静的シングルデリゲートの例(引数2つ)
      エレキベア
      エレキベア
      デリゲートは依存関係を制御するのにも便利クマね

      Unreal特有のライブラリ

      マイケル
      マイケル
      最後に、コンテナ、スマートポインタに限らず、C++標準のstdライブラリはほぼ独自でラップされています。 UnrealEngineに特化した処理内容になっていると思われますので、基本的にはUnrealのライブラリを使用するようにしましょう。
      主要のUnrealライブラリ
       
      Unrealライブラリ
      類似のstdライブラリ
      コンテナ
      TArray
      std::vector
      TMap
      std::map
      スマートポインタ
      TSharedPtr
      std::shared_ptr
      TWeakPtr
      std::weak_ptr
      TUniquePtr
      std::unique_ptr
      関数オブジェクト
      TFunction
      std::function

      参考:
      UnrealEngineドキュメント - スマートポインタ
      UnrealEngineドキュメント - コンテナ(TArray)

      エレキベア
      エレキベア
      スマートポインタ周りも一通り用意されているクマね

      UnrealC++のコーディング規約

      マイケル
      マイケル
      最後におまけにはなりますが、UnrealEngineには独自のコーディング規約が存在しています。 下記のような内容になっていて、いろいろ思うところもあると思いますが、エンジンのコードやコミュニティはこの形式が多いと思うのでなるべく合わせるようにしましょう!

      UnrealEngineドキュメント - コーディング規約

      • 変数名の頭は全て大文字にする
      • クラス名の頭には所定の接頭辞を付ける
      • ブール変数の頭にはbを付ける
      • constを正しく設定する
      • アクセス修飾子はpublic->privateの順で記述する
      • autoは基本的に使用しない
      • インクルードより前方宣言を優先する
      エレキベア
      エレキベア
      変数名大文字は特になんとも言えないクマね・・・

      おわりに

      マイケル
      マイケル
      というわけで、今回はUnrealC++の概要についてでした! どうだったかな??
      エレキベア
      エレキベア
      大体イメージは分かった気がするクマ〜〜〜 でもやっぱり実際に書いてみないとパッとしないクマね
      マイケル
      マイケル
      次回からは実際に制作したゲームでの実装内容を見ていきます! Unity等で開発経験があれば大体のイメージは掴めると思いますので、お楽しみに!
      エレキベア
      エレキベア
      早くC++を書きたいクマ〜〜〜
      マイケル
      マイケル
      それでは今回はこの辺で! アデューー!!
      エレキベア
      エレキベア
      クマ〜〜〜〜

      【UE5】第一回 ミニゲーム制作で学ぶUnrealC++ 〜UnrealC++の概要 編〜 〜完〜

      【UE5】第一回 ミニゲーム制作で学ぶUnrealC++ 〜UnrealC++の概要 編〜
      2024-05-18
      【UE5】第二回 ミニゲーム制作で学ぶUnrealC++ 〜キャラクター・ゲーム実装 編〜
      2024-05-18
      【UE5】第三回 ミニゲーム制作で学ぶUnrealC++ 〜UI・仕上げ実装 編〜
      2024-05-18

      UnrealEngineC++制作日記ミニゲームUE5
      2024-05-18

      関連記事
      【UE5.5】Nanite、Lumen、VSMの概要についてまとめる
      2025-05-12
      【UE5】Niagara SimulationStageによるシミュレーション環境構築
      2024-05-30
      【UE5】第三回 ミニゲーム制作で学ぶUnrealC++ 〜UI・仕上げ実装 編〜
      2024-05-18
      【UE5】第二回 ミニゲーム制作で学ぶUnrealC++ 〜キャラクター・ゲーム実装 編〜
      2024-05-18
      【JUCE】DTMプラグインを作ってみる 〜ディストーション編〜【VST/AU】
      2024-03-22
      【Unity】「怪盗チョコレート」をリリース!工夫点や反省点をざっと振り返る【バレンタイン】
      2023-02-12
      【DirextX12】第四回 DirextX12を使ったゲーム開発 〜FBX SDKを使用した3Dモデル描画〜
      2022-12-07
      【DirextX12】第三回 DirextX12を使ったゲーム開発 〜座標変換と3Dオブジェクト表示〜
      2022-11-27