アンリアる! C++入門編 ~対話形式で学ぶUnreal Engine~
BOOTHでUnreal Engine C++入門書を販売していますUnreal Engine上でC++を使って開発するために必要となる基礎知識を一冊の本にまとめた本です。 対話形式によるわかりやすい説明を目指しました。無料の試し読みも可能ですので、ぜひ読んでみてください!
[UE5] Construction Scriptを意図的に実行する方法

Unreal Engineでは、Level上に配置されているActorの変数の値を変更したり、Actorを移動したりすると、Construction Script(コンストラクションスクリプト)が自動的に実行されます。
複数の変数を連動して変更するなど、Levelエディタ上での編集作業を効率化するために非常に便利な機能です。

Construction Scriptが実行されるタイミングは決まっていますが、通常では実行されないタイミングで意図的に(強制的に)呼び出したいことはないでしょうか。
例えば、あるActorが実行されたら別のActorも実行する、複数のActorを一斉に実行する、ある処理で再実行するなどです。

本記事では、Construction Scriptを意図的に実行する方法を説明します。
なお、本手法を実現するためにはC++での実装が必要です。
汎用的に使えるよう、BP(ブループリント)で実行できるようにする方法も説明します。

※本手法はゲームプレイ中でも実行できますが、安全でない可能性があります。

Construction Scriptが自動的に実行されるタイミング

通常Construction Scriptは、Actorに対する以下の操作で自動的に実行されます(代表的なもの)。

  • メンバ変数の値を変更
  • 移動・回転・拡大
  • BPエディタ上でコンパイル実行

Construction Scriptで実行される処理は、ActorのBPエディタ画面のConstruction Scriptに記載します。

Construction Scriptの記載

Construction Scriptを意図的に実行する方法

それでは、サンプルを示しながら、Construction Scriptを好きなタイミングで意図的に実行する方法を説明します。
先に方法を一言でまとめると、Actorのメンバ関数RerunConstructionScriptsを呼び出すことで実現できます。

サンプルの仕様

以下のようなサンプルを作成します。

  • C++で、Actorの派生クラスActorA
    BPで、Actorの派生クラスActorBを作成し、Level上に配置する。
  • ActorAクラスは、TObjectPtr型(UE4ではAActor*型)のメンバ変数TargetActorを持つ。
    TargetActor変数には、Level上に配置したActorBを設定する。
  • ActorAクラスは、Construction Script実行の際、画面上に"A called"を表示するとともに、
    TargetActor変数に設定されているActorのConstruction Scriptを実行する。
  • ActorBクラスは、Construction Script実行の際、画面上に"B called"を表示する。

Construction Scriptの実行方法

ActorクラスにはConstruction Scriptを実行するメンバ関数が存在します。
それが、RerunConstructionScripts関数です。

RerunConstructionScripts()

この関数はBPでは呼び出すことができず、C++でのみ呼び出し可能です。
(後ほど、BPで呼び出す方法を説明します。)

この関数を呼び出すことで、Construction Scriptを意図したタイミングで実行可能です。
実行対象のActorを指定することで、自分自身以外のConstruction Scriptの実行も可能です。

サンプルのActorの実装

ActorAクラスのC++ソースコードを以下に示します。
プロジェクト名はMyProjectとしています。
C++では、Construction Scriptの処理はOnConstruction関数に記載します。
OnConstruction関数で、先ほどのRerunConstructionScripts関数を呼び出します。

ヘッダファイル(ActorA.h)

#pragma once

#include "GameFramework/Actor.h"
#include "ActorA.generated.h"
    
UCLASS()
class MYPROJECT_API AActorA : public AActor
{
    GENERATED_BODY()
    
public:
    virtual void OnConstruction(const FTransform& Transform) override;
    
    UPROPERTY(EditAnywhere)
    TObjectPtr< AActor > TargetActor;    // TObjectPtr< AActor > is AActor* in UE4
};

ソースファイル(ActorA.cpp)

#include "ActorA.h"

void AActorA::OnConstruction(const FTransform& Transform)
{
	Super::OnConstruction(Transform);

    GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, "A called");
    if (TargetActor) {
        TargetActor->RerunConstructionScripts();
    }
}

 
次に、ActorBクラスのBPを以下に示します。
Construction Scriptに処理を記載します。

ActorBクラスのBP

サンプルの実行

作成したActorAActorBを、Level上に配置します。
(C++で作成したActorAをそのまま配置すると移動できないので、BPでActorAの派生クラスを作成した上で配置します。)
配置したActorATargetActor変数に、配置したActorBを設定します。
Actorの配置・設定

ActorAを移動したり、何らの変数を変更し、ActorAのConstruction Scriptを実行させてみましょう。
画面上に"A called"と"B called"が表示され、ActorAと同時にActorBのConstruction Scriptが実行されていることが確認できます。

Construction Scriptの同時実行

以上のように、RerunConstructionScripts関数を呼び出すことで、意図的にConstruction Scriptを実行させることができます。
今回は、あるActorから別のActorのConstruction Scriptを実行する処理を例として挙げましたが、RerunConstructionScripts関数は任意のタイミングで呼び出し可能です。

BPでも意図的に実行できるようにする方法

C++でしかConstruction Scriptを意図的に実行できないのは不便に感じると思います。
そこで、BP関数ライブラリでRerunConstructionScripts関数を呼び出すBP関数を作成すれば、BPでも呼び出し可能になります。

RerunConstructionScripts関数はC++でしか呼び出せないため、C++でBP関数ライブラリを作成します。
C++のソースコードの一例を以下に示します。
ライブラリ関数名はMyFunctionLibraryとしています。
AActor*型を入力として受け取り、そのActorのRerunConstructionScripts関数を実行します。

ヘッダファイル(MyFunctionLibrary.h)

#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyFunctionLibrary.generated.h"

UCLASS()
class MYPROJECT_API UMyFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:
	UFUNCTION(BlueprintCallable)
	static void RerunConstructionScripts(AActor* Target);
};

ソースファイル(MyFunctionLibrary.cpp)

#include "MyFunctionLibrary.h"

void UMyFunctionLibrary::RerunConstructionScripts(AActor* Target)
{
    if (Target) {
        Target->RerunConstructionScripts();
    }
}

このライブラリ関数を利用して、先述のサンプルのActorAクラスをBPで作成することができます。

ActorAクラスのBP

このように、BP関数ライブラリで作成しておけば、C++だけでなくBPでもConstruction Scriptを意図的に実行することが可能になります。

まとめ

本記事のポイントは以下のとおりです。

  • Actorクラスのメンバ関数RerunConstructionScriptsにより、Construction Scriptを意図的に実行することが可能
  • BP関数ライブラリでRerunConstructionScripts関数を呼び出すBP関数を作成すれば、BPでもConstruction Scriptを意図的に実行することが可能

以上が、Construction Scriptを意図的に実行する方法です。

【宣伝】
Colory Gamesでは、Unreal Engine C++の入門書をBoothで販売しています。
対話形式でわかりやすく説明しています。

PrintString関数