Unreal Engine (UE)での開発において、C++ はパフォーマンスが求められる処理や複雑なゲームロジックの中核を担い、Blueprint は迅速なプロトタイピングやデザイナーによる直感的なロジック構築を可能にする、まさに両輪の関係にあります。
しかし、多くの初心者や中級者が直面する課題があります。それは、「C++で書いた便利な関数や変数を、どうすればBlueprintから簡単に、安全に呼び出せるのか? 」という点です。せっかくC++で効率的なコードを書いても、Blueprintから使えなければ、その恩恵を十分に受けられません。
本記事では、このC++とBlueprintの連携をスムーズに行うための核となる仕組み、特にUFUNCTION とUPROPERTY マクロの使い方に焦点を当て、具体的なコード例とベストプラクティスを交えて徹底的に解説します。この記事を読めば、あなたのUE開発の幅が格段に広がるでしょう。
UCLASS・UFUNCTION・UPROPERTYの概要
C++のコードをBlueprintの世界に公開するためには、Unreal Engineのリフレクションシステム にその存在を教える必要があります。この役割を果たすのが、UCLASS、UFUNCTION、UPROPERTYといった特別なマクロ群です。
UCLASS: クラスの登録
まず、Blueprintからアクセスしたいクラスには、必ずUCLASS()マクロを付与する必要があります。これは、そのクラスがUEのリフレクションシステムによって追跡・管理されるべきであることを示します。
// MyActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
UCLASS() // このマクロが必須
class MYPROJECT_API AMyActor : public AActor
{
GENERATED_BODY()
public:
AMyActor();
};
UPROPERTY: 変数の公開
C++で定義した変数をBlueprintから参照したり、編集したりできるようにするには、その変数にUPROPERTY()マクロを付与します。このマクロの引数(指定子)によって、Blueprintでの振る舞いを細かく制御できます。
| 指定子 | 意味 | Blueprintでの振る舞い |
|---|---|---|
EditAnywhere | どこからでも編集可能 | 詳細パネルで編集可能(インスタンス、デフォルト) |
BlueprintReadOnly | Blueprintから読み取り専用 | Blueprintグラフで値の取得ノードが生成される |
BlueprintReadWrite | Blueprintから読み書き可能 | Blueprintグラフで値の取得/設定ノードが生成される |
VisibleAnywhere | どこからでも参照可能 | 詳細パネルで値の参照のみ可能 |
Category = "My Category" | 詳細パネルでの表示カテゴリ | カテゴリ分けされ、整理しやすくなる |
コード例(UPROPERTY):
// MyActor.h
// ...
UCLASS()
class MYPROJECT_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Blueprintから読み書き可能で、詳細パネルで編集できる変数
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float Health = 100.0f;
// Blueprintから読み取り専用の変数
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
int32 MaxAmmo = 30;
};
UFUNCTION: 関数の公開
C++で実装したロジックをBlueprintから呼び出すには、その関数にUFUNCTION()マクロを付与します。
| 指定子 | 意味 | Blueprintでの振る舞い |
|---|---|---|
BlueprintCallable | Blueprintから呼び出し可能 | 標準的な関数ノードとして利用可能 |
BlueprintPure | 純粋関数(Pure Function)として呼び出し可能 | 実行ピンがなく、戻り値のみを持つノードとして利用可能(状態を変更しない関数に推奨) |
BlueprintImplementableEvent | C++で宣言し、Blueprintで実装するイベント | Blueprintでイベントノードとしてオーバーライド可能 |
BlueprintNativeEvent | C++でデフォルト実装を持ち、Blueprintでオーバーライド可能 | C++とBlueprintの両方で実装を持つことができる |
コード例(UFUNCTION):
// MyActor.h
// ...
UCLASS()
class MYPROJECT_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// 1. Blueprintから呼び出し可能な関数
UFUNCTION(BlueprintCallable, Category = "Combat")
void ApplyDamageToHealth(float DamageAmount);
// 2. Blueprintから呼び出し可能な純粋関数(Pure Function)
UFUNCTION(BlueprintPure, Category = "Stats")
float GetHealthPercentage() const;
// 3. Blueprintで実装するイベント
UFUNCTION(BlueprintImplementableEvent, Category = "Events")
void OnHealthDepleted();
};