C++ とブループリント

ゲームプレイ プログラマ向けの Unreal Engine 入門情報

コンテンツ

C++ クラスをブループリントで拡張できます。プログラマーが、新しいゲームプレイ クラスをコードで作成し、それをレベル デザイナーがブループリントで設定および変更することができます。 C++ クラスがどのようにブループリント システムとインタラクションするかを変える多数の指定子があります。この例では、その一部を取り上げて説明します。

クラス設定

クラス設定の最初のセクションでは、C++ クラス ウィザード を使用して LightSwitchBoth という名前のクラスを作成します。

LightSwitchBoth クラスの大部分のコード設定は、C++ Only LightSwitch example のコードと類似しています。ブループリントで LightSwitchCodeOnly クラスの拡張が可能でも、 そのクラスで作成されたコンポーネント、変数、関数は、ブループリント グラフにアクセスすることはできません。この例では、 LightSwitchBoth クラスから派生するブループリントのテンプレートとして機能させる UPROPERTY()と`UFUNCTION()` 指定子について理解を深めていきます。

最初に、C++ Only LightSwitch の例で、LightSwitch コンポーネント、 Sphere コンポーネント、 DesiredIntensity 変数、そして OnOverlap 関数を作成するためにヘッダ ファイルとソース ファイルがどのように設定されているかをご覧になると良いでしょう。

ヘッダファイルは、以下の機能を追加するために、C++ Only LightSwitch から適用されます。

  • PointLight コンポーネントと Sphereコンポーネントは BlueprintReadOnly です。[My Blueprint] タブの [Switch Component] カテゴリに表示されます。

  • OnOverlapBegin と OnOverlapEnd は BlueprintNativeEvent になりました。[My Blueprint] タブの [Switch Functions] カテゴリに表示されます。

  • DesiredIntensity は BlueprintReadWrite です。[My Blueprint] タブの [Switch Variables] カテゴリに表示されます。

  • DesiredIntensity は VisibleAnywhere の代わりに EditAnywhere となりました。

UCLASS()マクロには Blueprintable な指定子があります。このケースでは不要です。LightSwitchBoth は、Blueprintable アクタから直接継承し、そのBlueprintable 指定子が継承されるからです。

UPROPERTY() マクロと UFUNCTION() マクロの指定子の追加で、LightSwitchBoth クラスのヘッダファイルは以下のようになります。

LightSwitchBoth.h

    // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

    #pragma once

    #include "GameFramework/Actor.h"
    #include "LightSwitchBoth.generated.h"

    /**
     *
     */
    UCLASS()
    class [PROJECTNAME]_API ALightSwitchBoth : public AActor
    {
        GENERATED_BODY()
        public:
        /** point light component */
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Switch Components")
        class UPointLightComponent* PointLight1;

        /** sphere component */
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Switch Components")
        class USphereComponent* Sphere1;

        ALightSwitchBoth();

        /** called when something enters the sphere component */
        UFUNCTION(BlueprintNativeEvent, Category="Switch Functions")
        void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

        void OnOverlapBegin_Implementation(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

        /** called when something leaves the sphere component */
        UFUNCTION(BlueprintNativeEvent, Category="Switch Functions")
        void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

        void OnOverlapEnd_Implementation(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

        /** Toggles the light component's visibility*/
        UFUNCTION()
        void ToggleLight();

        /** the desired intensity for the light */
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Switch Variables")
        float DesiredIntensity;

    };

LightSwitchBoth のソース ファイルでは、コンストラクタに変更はありません。しかし、OnOverlapBegin 関数と OnOverlapEnd 関数に変更を加える必要があります。こうした関数は BlueprintNativeEvent となりました。つまり、このクラスから派生するブループリントに、OnOverlapBegin と`OnOverlapEnd` をオーバーライドするイベントを配置して、通常関数が呼ばれるタイミングでこれを実行することができます。

こうしたイベントのひとつが存在しない場合、 C++ コードで実装した関数を代わりに実行します。この設定を機能させるには、C++ 関数を`OnOverlapBegin_Implementation と`OnOverlapEnd_Implementation に名前を変えなくてはいけません。ブループリントの設定は、この例の後の方で取り上げます。

OnOverlapBeginOnOverlapEnd の定義に変更を加えると、LightSwitchBoth のソースファイルは以下のようになります。

LightSwitchBoth.cpp

    // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

    #include "BasicClasses.h"
    #include "LightSwitchBoth.h"

    ALightSwitchBoth::ALightSwitchBoth()
    {

        DesiredIntensity = 3000.0f;

        PointLight1 = CreateDefaultSubobject<UPointLightComponent>(TEXT("PointLight1"));
        PointLight1->Intensity = DesiredIntensity;
        PointLight1->bVisible = true;
        RootComponent = PointLight1;

        Sphere1 = CreateDefaultSubobject<USphereComponent>(this, TEXT("Sphere1"));
        Sphere1->InitSphereRadius(250.0f);
        Sphere1->SetupAttachment(RootComponent);

        Sphere1->OnComponentBeginOverlap.AddDynamic(this, &ALightSwitchBoth::OnOverlapBegin);       // set up a notification for when this component overlaps something
        Sphere1->OnComponentEndOverlap.AddDynamic(this, &ALightSwitchBoth::OnOverlapEnd);       // set up a notification for when this component overlaps something
    }

    void ALightSwitchBoth::OnOverlapBegin_Implementation(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
    {
        if (OtherActor && (OtherActor != this) && OtherComp)
        {
            ToggleLight();
        }
    }

    void ALightSwitchBoth::OnOverlapEnd_Implementation(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
    {
        if (OtherActor && (OtherActor != this) && OtherComp)
        {
            ToggleLight();
        }
    }

    void ALightSwitchBoth::ToggleLight()
    {
        PointLight1->ToggleVisibility();
    }

これが空のプロジェクトに追加した最初のコード クラスである場合は、エディタを閉じて、Visual Studio または Xcode でプロジェクトをコンパイルした後に、エディタを開いてプロジェクトを再び開く必要があります。 ゲームモジュールが適切に作成されて再ロードされていることを確認するためです。プロジェクトを開くために使用しているアンリアル エディタの実行ファイルのバージョンが Build Configuration と同じであることの確認も重要となります。ビルド設定とプロジェクトのコンパイルに関する詳細は「ゲーム プロジェクトのコンパイル」ページをご覧ください。

コードを既存の C++ プロジェクトに追加する場合は、ホットリロード機能を使用してエディタ内で新規コードをコンパイルすることができます。

この新規クラスをコンパイル後に、新規の ブループリント クラス作成 することができます。 この場合、ブループリントの親クラスに LightSwitchBoth を選択して、名前を LightSwitchBoth_BP とします。

BPBoth_ParentClass.png

C++ に追加した PointLight コンポーネントと Sphere コンポーネントも ブループリント エディタ[コンポーネント] タブに表示されます。 アイコンはダーク ブルーで表示されて、ネイティブ コンポーネントであること、親 LightSwitchBoth クラスから継承されたことを示します。単に LightSwitchBoth_BP ブループリントに追加された新規コンポーネントは、ライトブルーのアイコンになります。[コンポーネント] タブを使用したコンポーネントの追加と配置についての詳しい情報は、Components タブのドキュメントを参照してください。

Both_ComponentList.png

ブループリント エディタ[グラフ] パネル はブループリント編集の中心部分です。[グラフ] パネルでは、新しい 変数関数マクロブループリント エディタ の My Blueprint タブで追加することができます。 Blueprint クラスに含まれている全ての グラフ にも アクセスできます。グラフには、クラスの変数、gameplay event、さらにアクタの周囲のものなどで操作するデザイン タイムとゲームプレイ機能を作成するために ノード が接続されています。

[グラフ] パネルの [My Blueprint] タブには、C++ コードで LightSwitchBoth クラスに追加した PointLight コンポーネントと Sphere コンポーネントが表示されます。これは BlueprintReadOnly 指定子によって表示されます。これらのコンポーネントのノードは、[My Blueprint] タブから名前をクリックしてグラフにドラッグすることで、グラフに追加することができます。その後、こうしたノードを、可視性やライト色などの変数を変更するノードに接続することができます。[DesiredIntensity] 変数は [My Blueprint] タブにも表示されます。コンポーネントではなく変数であるため、BlueprintReadWrite 指定子を使用できます。つまり、ブループリント グラフに DesiredIntensity の値を get および set するノードの作成が可能です。使用に関する一般情報については ブループリント エディタ の My Blueprint のドキュメントを参照してください。

親の LightSwitchBoth クラスのコンポーネントと変数は、デフォルトで表示されない場合もあります。[My Blueprint] タブの下にある [Show inherited variables(継承した変数を表示)] チェックボックスにチェックを入れると、 親クラスから継承された変数が表示されます。

全ての変数を表示

ユーザー作成の変数のみを表示

showInhVar2.PNG

showInhVar.PNG

BP_Only_MyBlueprint.png

Both_MyBlueprint.png

LightSwitchBoth_BP クラスの挙動をセットアップするために使用するグラフが 2 つあります。1 つめは、コンストラクション スクリプト グラフで、 特殊な Construction Script event を含みます。Construction Script 設定無しの状態では、新規の LightSwitchBoth_BP アクタは、LightSwitchBoth コンストラクタのみを使用します。しかし、アクタがレベル内で移動した時と DesiredIntensity の変更時に、 Construction Script は実行されます。Construction Script を使用するということは、ブループリントに公開されたアクタ変数を簡単に変更することが可能であり、 変更がもたらす効果を直ぐに確認できることを意味します。

LightSwitchBoth_BP クラスで、Construction Script イベントは Set Intensity ノードと接続しています。 これは、 Point Light 1 (PointLight コンポーネント) のBrightness (輝度) が、アクタの追加時、レベル内で移動時、または [DesiredIntensity] が変更された時に DesiredIntensity の値に設定されるようにするためです。

Both_ConstructionScript.png

LightSwitch_BPOnly クラスでセットアップされたもうひとつのグラフは、EventGraph です。イベントグラフの実行は、イベントから開始します。この場合、C++ 関数 OnOverlap が呼ばれると常にOnOverlap event が実行されます。LightSwitchBoth ソース ファイルでは、デリゲートはアクタが Sphere コンポーネントへ入った時またはそこから離れた時に OnOverlap が実行するように設定されています。

    Sphere1->OnComponentBeginOverlap.AddDynamic(this, &ALightSwitchBoth::OnOverlapBegin);       // set up a notification for when this component overlaps something
    Sphere1->OnComponentEndOverlap.AddDynamic(this, &ALightSwitchBoth::OnOverlapEnd);       // set up a notification for when this component overlaps something

OnOverlap event ノードは、Set Light Color ノードと接続されています。イベントが実行されると、常に PointLight コンポーネントのライト色をランダムな色にするように設定されています。これは、PointLight コンポーネントの可視性を切り替える、ソースファイルの OnOverlap_Implementation 関数をオーバーライドします。

イベントおよびグラフでの作業に関する詳しい情報は、イベントEventGraph、および ブループリント クラス UI のドキュメントをご覧ください。

Both_EventGraph_2.png

DesiredIntensity 変数は、LightSwitchBoth ヘッダファイルで EditAnywhere に設定されます。そのため、ブループリント エディタ のデフォルトで可視状態であり、クラスのデフォルト ボタンをクリックして、 [Details (詳細)] パネルでクラスのデフォルトを見て編集することができます。 これは、クラスの各インスタンスに対して、変数の変更が可能であることも意味します。そのため、各アクタは独自の DesiredIntensity を保持することができます。DesiredIntensity は BlueprintReadWrite でもあるため、これをコンストラクション スクリプトで使用すると、 更新された時にコンストラクション スクリプトが再び実行されることになります。

Both_Defaults.png

ブループリントに作成したクラスは、別のブループリント クラスへ拡張することができます。新規ブループリントを作成するには クラスビューア のクラスの横にあるドロップダウンボタンをクリックするか、ブループリントを 右クリック して、[Create New Blueprint Based on This] を選択します。

ブループリント クラス、 LightSwitchBoth_BP はコンテンツ ブラウザ にあり、そこからレベルにドラッグできます。クラス ビューアー にもあります。 コンテンツ ブラウザまたはクラスビューアを使用したレベルへのアクタの配置については、アクタを配置する のドキュメントを参照してください。

Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
キャンセル