ブループリントは、Unreal Engine 4でゲームプレイを作成する非常に一般的な方法です。ただし、長い間プログラミングしてコードを好んでいるなら、C ++が理想的です。 C ++を使用すると、エンジンに変更を加えて独自のプラグインを作成することもできます。
このチュートリアルでは、次のことを学びます。
- C ++クラスを作成する
- コンポーネントを追加し、ブループリントに表示する
- C ++クラスに基づいてブループリントクラスを作成する
- 変数を追加し、ブループリントから可変にします
- 軸とアクションのバインディングを関数に関連付けます
- ブループリントのC ++関数をオーバーライドする
- 衝突イベントを機能に関連付ける
これはC ++の学習に関するチュートリアルではないことを考慮する価値があります。 Unreal EngineのコンテキストでC ++を使用することに焦点を当てます。
注:このチュートリアルでは、Unreal Engineの基本をすでに理解していることを前提としています。 Unreal Engineを初めて使用する場合は、まず初心者向けの 10部構成のUnreal Engineチュートリアルをご覧ください 。
仕事を始める
まだ行っていない場合は、 Visual Studioをインストールする必要があります。 Unreal Engine 4用のVisual Studioのセットアップについては、 公式の Epic マニュアルの指示に従ってください(代替IDEを使用できますが、Unrealは動作するように設計されているため、このチュートリアルではVisual Studioを使用します)。
次に、 プロジェクトブランクをダウンロードして解凍します。 プロジェクトフォルダーに移動し、 CoinCollector.uprojectを開きます 。 アプリケーションがモジュールを再構築するように求められたら、[ はい ]をクリックします。
これを完了すると、次のシーンが表示されます。
このチュートリアルでは、コインを収集するためにプレーヤーが移動するボールを作成します。 前のチュートリアルでは、ブループリントを使用してプレイヤーが制御するキャラクターを使用しました。 このチュートリアルでは、C ++を使用して作成します。
C ++クラスの作成
C ++クラスを作成するには、コンテンツブラウザに移動し、[ 新規追加]> [ 新しいC ++クラス]を選択します。
その後、C ++クラスウィザードが開きます。 まず、継承するクラスを選択する必要があります。 クラスはプレイヤー主導でなければならないため、Pawnが必要です。 Pawnを選択し、 Nextをクリックします。
次の画面で、.hおよび.cppファイルの名前とパスを指定できます。 NameをBasePlayerに置き換え、 Create Classをクリックします 。
これにより、ファイルが作成され、プロジェクトがコンパイルされます。 コンパイル後、UnrealはVisual Studioを開きます。 BasePlayer.cppとBasePlayer.hが開いていない場合は、ソリューションエクスプローラーに移動して開きます。 これらは、 Games \ CoinCollector \ Source \ CoinCollectorフォルダにあります 。
先に進む前に、 Unrealのリフレクションシステムについて知る必要があります 。 このシステムは、詳細パネルやガベージコレクションなど、エンジンのさまざまな部分を管理します。 C ++ Class Wizardを使用してクラスを作成すると、Unrealエンジンはタイトルに3行を追加します。
#include "TypeName.generated.h"
-
UCLASS()
-
GENERATED_BODY()
Unrealエンジンは、クラスをリフレクションシステムから見えるようにするためにこれらの行を必要とします。 これが明確でない場合でも心配する必要はありません。 リフレクションシステムにより、ブループリントの関数や変数をエディターに展開するなどのことができることを知っておく必要があります。
また、クラスが
ABasePlayer
ではなく
BasePlayer
と呼ばれていることに
ABasePlayer
かもしれませ
BasePlayer
。 タイプactorのクラスを作成するとき、Unrealはクラス名の前に接頭辞A (単語actorから)を付けます。 リフレクションシステムが機能するには、クラスに適切なプレフィックスが必要です。 Epic Code Standardのプレフィックスの詳細をご覧ください。
注:プレフィックスはエディターに表示されません。 たとえば、 ABasePlayer型の変数を作成する必要がある場合は、 BasePlayerを探す必要があります。
反射システムについて知る必要があるのはこれだけです。 次に、プレーヤーモデルとカメラを追加する必要があります。 これを行うには、 コンポーネントを使用します 。
コンポーネントを追加する
Pawnプレーヤーの場合、3つのコンポーネントを追加する必要があります。
- 静的メッシュ:プレイヤーモデルであるメッシュを選択できます
- スプリングアーム:このコンポーネントは、カメラの三脚として使用されます。 一端がメッシュに取り付けられ、カメラがもう一端に取り付けられます。
- カメラ: Unrealは、カメラが見るすべてのものをプレーヤーに表示します。
まず、各タイプのコンポーネントにヘッダーを追加する必要があります。 BasePlayer.hを開き、
#include "BasePlayer.generated.h"
上に次の行を追加します。
#include "Components/StaticMeshComponent.h" #include "GameFramework/SpringArmComponent.h" #include "Camera/CameraComponent.h"
注: .generated.hファイルを最後に追加することが重要です。 この場合、インクルードディレクティブは次のようになります。
#include "CoreMinimal.h" #include "GameFramework/Pawn.h" #include "Components/StaticMeshComponent.h" #include "GameFramework/SpringArmComponent.h" #include "Camera/CameraComponent.h" #include "BasePlayer.generated.h"
最後のインクルードでない場合、コンパイル時にエラーが発生します。
次に、各コンポーネントの変数を宣言する必要があります。
SetupPlayerInputComponent()
後に次の行を追加します。
UStaticMeshComponent* Mesh; USpringArmComponent* SpringArm; UCameraComponent* Camera;
ここで使用される名前は、エディター内のコンポーネントの名前になります。 この場合、コンポーネントはMesh 、 SpringArmおよびCameraとして表示されます。
次に、各変数を反射システムから見えるようにする必要があります。 これを行うには、各変数の上に
UPROPERTY()
追加します。 これで、コードは次のようになります。
UPROPERTY() UStaticMeshComponent* Mesh; UPROPERTY() USpringArmComponent* SpringArm; UPROPERTY() UCameraComponent* Camera;
UPROPERTY()
)に
UPROPERTY()
を追加することもでき
UPROPERTY()
。 これらは、エンジンのさまざまな側面で変数の動作を制御します。
各
UPROPERTY()
括弧内に
VisibleAnywhere
と
BlueprintReadOnly
を追加します。 各記述子はコンマで区切ります。
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
VisibleAnywhere
使用すると、各コンポーネントをエディター(ブループリントを含む)で表示できます。
BlueprintReadOnly
使用すると、ブループリントノードを使用してコンポーネントへのリンクを取得できます。 ただし、コンポーネントを定義することはできません。 コンポーネントは変数であるため、コンポーネントは読み取り専用であることが重要です。 ユーザーに尋ねて欲しくありません 。そうしないと、メモリ内のランダムな場所を示す場合があります。
BlueprintReadOnly
使用すると、コンポーネント内で変数を設定できることに注意してください。これがまさに私たちが目指していることです。
注:ポインターではない変数(int、float、booleanなど)の場合は、EditAnywhere
とBlueprintReadWrite
使用します。
各コンポーネントの変数ができたので、それらを初期化する必要があります。 これを行うには、 コンストラクター内で作成します。
コンポーネントの初期化
CreateDefaultSubobject<Type>("InternalName")
を使用してコンポーネントを作成できます。 BasePlayer.cppを開き、次の行を
ABasePlayer()
追加します。
Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh"); SpringArm = CreateDefaultSubobject<USpringArmComponent>("SpringArm"); Camera = CreateDefaultSubobject<UCameraComponent>("Camera");
これにより、各タイプのコンポーネントが作成され、渡された変数のメモリにアドレスが割り当てられます。 文字列引数は、エンジンで使用されるコンポーネントの内部名になります(この例では同じですが、表示名ではありません )。
次に、階層を設定する必要があります(ルートコンポーネントを選択するなど)。 前のコードの後に次を追加します。
RootComponent = Mesh; SpringArm->SetupAttachment(Mesh); Camera->SetupAttachment(SpringArm);
最初の行は、
Mesh
ルートコンポーネントにします。 2行目は、
SpringArm
を
Mesh
アタッチします。 最後に、3行目で
Camera
を
SpringArm
接続し
SpringArm
。
コンポーネントコードの完成後、コンパイルする必要があります。 次のコンパイル方法のいずれかを選択します。
- Visual Studioで、 ビルド\ソリューションのビルドを選択します
- アンリアルエンジンで、 ツールバーの [ コンパイル ]をクリックします
次に、使用するメッシュとスプリングレバーの回転を指定する必要があります。 C ++でリソースパスをハードコードすることは望ましくないため、ブループリントでこれを行うことをお勧めします。 たとえば、C ++で静的メッシュを設定するには、同様のことを行う必要があります。
static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshToUse(TEXT("StaticMesh'/Game/MyMesh.MyMesh"); MeshComponent->SetStaticMesh(MeshToUse.Object);
ただし、ブループリントでは、ドロップダウンリストからメッシュを選択するだけで十分です。
リソースを別のフォルダーに移動しても、ブループリントでは何も悪くなりません。 ただし、C ++では、このリソースへのすべてのリンクを変更する必要があります。
ブループリントでメッシュとスプリングレバーの回転を設定するには、 BasePlayerに基づいたブループリントを作成する必要があります。
注:通常、C ++で基本クラスを作成してから、サブクラスブループリントを作成するのが実用的です。 これにより、アーティストやデザイナーのクラスを簡単に変更できます。
C ++クラスのサブクラス化
Unreal Engineで、 Blueprintsフォルダーに移動してBlueprint Classを作成します。 [ すべてのクラス]セクションを展開し、 BasePlayerを見つけます 。 BasePlayerを選択し 、[ 選択 ]をクリックします。
名前をBP_Playerに変更してから開きます。
まず、メッシュを設定します。 Meshコンポーネントを選択し、そのStatic MeshをSM_Sphereに設定します。
次に、スプリングレバーの回転と長さを設定する必要があります。 私たちのゲームは上面図になりますので、カメラはプレーヤーの上になければなりません。
SpringArmコンポーネントを選択し、 回転を(0、 -50、0 )に設定します。 これにより、カメラがメッシュを見下ろすようにスプリングレバーが回転します。
スプリングレバーはメッシュの子であるため、ボールが回転し始めると回転し始めます。
GIF
これを修正するには、レバーの回転が絶対であることを確認する必要があります。 [ 回転]の横にある矢印をクリックして、[ ワールド]を選択します。
GIF
次に、 ターゲットアームの長さを1000に設定します 。 そのため、カメラをメッシュから1000ユニット離れたところに移動します。
次に、デフォルトのポーンクラスを設定して、ポーンを使用する必要があります。 [ コンパイル]をクリックして、エディターに戻ります。 World Settingsを開き、 Default PawnをBP_Playerに設定します 。
[ プレイ]をクリックして、ゲームのポーンを確認します。
次のステップは、プレーヤーが動き回れるようにプレーヤーに機能を追加することです。
モーション実装
移動に変位を追加する代わりに、物理学を使用して移動します! まず、ボールに加えられる力の大きさを示す変数が必要です。
Visual Studioに戻り、 BasePlayer.hを開きます 。 変数コンポーネントの後に次を追加します。
UPROPERTY(EditAnywhere, BlueprintReadWrite) float MovementForce;
EditAnywhere
では、詳細パネルで
MovementForce
を変更でき
EditAnywhere
。
BlueprintReadWrite
使用すると、Blueprintノードを使用して
MovementForce
を設定および読み取ることができます。
次に、2つの関数を作成する必要があります。 1つは上下に移動し、もう1つは左右に移動します。
モーション関数を作成する
MovementForce
下に次の関数宣言を追加します。
void MoveUp(float Value); void MoveRight(float Value);
後でこれらの軸バインディング関数を関連付けます。 このため、軸バインディングはスケールを転送できます(したがって、関数には
float Value
パラメーターが必要です)。
注:軸とスケールのバインドに慣れていない場合は、 ブループリントチュートリアルをご覧ください。
次に、各関数の実装を作成する必要があります。 BasePlayer.cppを開き、ファイルの最後に次を追加します。
void ABasePlayer::MoveUp(float Value) { FVector ForceToAdd = FVector(1, 0, 0) * MovementForce * Value; Mesh->AddForce(ForceToAdd); } void ABasePlayer::MoveRight(float Value) { FVector ForceToAdd = FVector(0, 1, 0) * MovementForce * Value; Mesh->AddForce(ForceToAdd); }
MoveUp()
は、X軸に沿って
Mesh
に物理的な強度を追加します。 強度値は
MovementForce
によって設定されます。 結果に
Value
(軸スナップスケール)を掛けることで、メッシュは正または負の方向に移動できます。
MoveRight()
は
MoveRight()
と同じですが、Y軸に沿っています 。
モーション関数の作成が完了したら、軸バインディングをそれらに関連付ける必要があります。
軸バインディングを関数に関連付ける
簡単にするために、事前に軸バインディングを作成しました。 これらはプロジェクト設定の入力セクションにあります。
注: Axisバインディングは、関連付けられている関数と同じ名前である必要はありません。
SetupPlayerInputComponent()
内に次のコードを追加します。
InputComponent->BindAxis("MoveUp", this, &ABasePlayer::MoveUp); InputComponent->BindAxis("MoveRight", this, &ABasePlayer::MoveRight);
したがって、 MoveUpおよびMoveRight軸のバインディングを
MoveUp()
および
MoveRight()
ます。
これで、ムーブメント機能が完成しました。 次に、 Meshコンポーネントの物理を有効にする必要があります。
物理的包含
ABasePlayer()
内に次の行を追加します。
Mesh->SetSimulatePhysics(true); MovementForce = 100000;
最初の行は、物理的な力が
Mesh
に作用することを許可します。 2行目は
MovementForce
を100000に設定します。 つまり、ボールが移動すると、100,000の力が追加されます。 デフォルトでは、物理オブジェクトの重量は約110キログラムなので、それらを移動するには多大な力が必要です。
サブクラスを作成すると、基本クラスでプロパティを変更しても、一部のプロパティは変更されません。 このケースでは、 BP_Playerで 物理シミュレーションを有効にしません。 ただし、作成されたすべてのサブクラスでは、デフォルトで有効になります。
コンパイルしてUnreal Engineに戻ります。 BP_Playerを開き、 Meshコンポーネントを選択します。 次に、 Simulate Physicsをオンにします。
[ コンパイル]をクリックし、[ 再生]をクリックします。 W 、 A 、 S、およびDを押してボールを移動します。
GIF
次に、ブループリントを使用して実装できるC ++関数を宣言します。 これにより、設計者はC ++を使用せずに機能を作成できます。 これを学習するために、ジャンプ関数を作成します。
ジャンプ機能を作成する
まず、ジャンプバインドを関数にバインドする必要があります。 このチュートリアルでは、スペースバーにジャンプを割り当てます 。
Visual Studioに戻り、 BasePlayer.hを開きます 。
MoveRight()
下に次の行を追加します。
UPROPERTY(EditAnywhere, BlueprintReadWrite) float JumpImpulse; UFUNCTION(BlueprintImplementableEvent) void Jump();
最初は、
JumpImpulse
と呼ばれるフロート変数
JumpImpulse
。 ジャンプを実装するときに使用できます。 彼女は、エディターで変更できるように
EditAnywhere
を使用します。 また、BlueprintReadWriteを使用しているため、Blueprintノードを使用して読み取りと書き込みを行うことができます。
次はジャンプ機能です。
UFUNCTION()
は、
Jump()
を反射システムに表示します。
BlueprintImplementableEvent
により、ブループリントは
Jump()
を実装できます。 実装がない場合、
Jump()
呼び出しは失敗します。
注: C ++でデフォルトの実装を作成する場合は、BlueprintNativeEvent
を使用します。 以下に、その方法について説明します。
Jumpはアクションバインディングであるため、バインディング方法はわずかに異なります。 BasePlayer.hを閉じてBasePlayer.cppを開きます 。
SetupPlayerInputComponent()
を
SetupPlayerInputComponent()
追加し
SetupPlayerInputComponent()
。
InputComponent->BindAction("Jump", IE_Pressed, this, &ABasePlayer::Jump);
これにより、 Jumpバインディングが
Jump()
バインドされます。 ジャンプキーを押したときにのみ実行されます。 キーを
IE_Released
たときに実行する場合は、
IE_Released
を使用し
IE_Released
。
次に、ブループリントで
Jump()
を再定義します。
ブループリントの関数をオーバーライドする
BasePlayer.cppをコンパイルして閉じます 。 次に、Unreal Engineに戻ってBP_Playerを開きます 。 [マイブループリント]パネルに移動し、[ 機能 ]にカーソルを合わせて、[ 上書き]ドロップダウンリストを表示します。 それをクリックして、 ジャンプを選択します。 そこで、 Event Jumpを作成します。
GIF
注:戻り値の型がない場合、オーバーライドはイベントになります。 戻り型が存在する場合、それは関数になります。
次に、次の図を作成します。
そのため、Z軸に沿って メッシュインパルス( JumpImpulse )を追加します 。 この実装では、プレーヤーは無限にジャンプできることに注意してください。
次に、 JumpImpulseの値を設定する必要があります。 ツールバーの「 クラスのデフォルト」をクリックして、「詳細」パネルに移動します。 JumpImpulseを100000に設定します。
[ コンパイル]をクリックし、 BP_Playerを閉じます 。 [ 再生]をクリックして、 スペースバーでジャンプしてみてください。
GIF
次のセクションでは、プレイヤーとの接触でコインが消えるようにします。
コインを集める
衝突を処理するには、関数をオーバーレイイベントに関連付ける必要があります。 このため、関数は2つの要件を満たしている必要があります。 まず、関数には
UFUNCTION()
マクロが必要です。 2番目の要件は、関数に正しい署名が必要であることです。 このチュートリアルでは、 OnActorBeginOverlapイベントを使用します。 このイベントには、関数に次の署名が必要です。
FunctionName(AActor* OverlappedActor, AActor* OtherActor)
Visual Studioに戻り、 BaseCoin.hを開きます 。
PlayCustomDeath()
下に次の行を追加します。
UFUNCTION() void OnOverlap(AActor* OverlappedActor, AActor* OtherActor);
バインド後、コインと別のアクターが適用されると、
OnOverlap()
が実行されます。
OverlappedActor
はコインになり、
OtherActor
別のアクターになります。
次に、
OnOverlap()
を実装する必要があります。
オーバーレイ実装
BaseCoin.cppを開き、ファイルの末尾に次を追加します。
void ABaseCoin::OnOverlap(AActor* OverlappedActor, AActor* OtherActor) { }
プレーヤーオーバーレイのみを認識したいので、
OtherActor
を
ABasePlayer
にキャストする必要があります。 キャストする前に、
ABasePlayer
ヘッダーを追加する必要があります。
#include "BaseCoin.h"
下に次を追加します。
#include "BasePlayer.h"
次に、キャストを実行する必要があります。 アンリアルエンジンでは、キャストは次のように実行できます。
Cast<TypeToCastTo>(ObjectToCast);
キャストが成功すると、
ObjectToCast
へのポインターを
ObjectToCast
ます。 失敗した場合、
nullptr
を返します。
nullptr
の結果を確認することで、オブジェクトに目的のタイプがあったかどうかを判断できます。
Inside
OnOverlap()
追加し
OnOverlap()
。
if (Cast<ABasePlayer>(OtherActor) != nullptr) { Destroy(); }
OnOverlap()
が実行されると、
OtherActor
タイプが
ABasePlayer
かどうかがチェックされます。 もしそうなら、それはコインを破壊します。
次に、
OnOverlap()
をバインドする必要があります。
オーバーレイ関数バインディング
関数をオーバーレイイベントに
AddDynamic()
には、
AddDynamic()
イベントをイベントに使用する必要があります。
ABaseCoin()
内部に追加し
ABaseCoin()
。
OnActorBeginOverlap.AddDynamic(this, &ABaseCoin::OnOverlap);
これは、
OnOverlap()
をOnActorBeginOverlapイベントに
OnOverlap()
方法です。 このイベントは、アクターが別のアクターとオーバーラップするときに常に発生します。
コンパイルしてUnreal Engineに戻ります。 [ 再生]をクリックして、コインの収集を開始します。 コインと接触すると、コインは破壊され、消滅します。
GIF
注:コインが消えない場合は、エディターを再起動して完全な再コンパイルを完了してください。 一部の変更には再起動が必要です。
次のセクションでは、もう1つ再定義可能なC ++関数を作成します。 ただし、今回はデフォルトの実装も作成します。 これを実証するために、
OnOverlap()
を使用します。
デフォルトの関数実装を作成する
デフォルトの実装で関数を作成するには、
BlueprintNativeEvent
記述子を使用する必要があります。 Visual Studioに戻り、 BaseCoin.hを開きます 。
OnOverlap()
追加
OnOverlap()
UFUNCTION()
BlueprintNativeEvent
:
UFUNCTION(BlueprintNativeEvent) void OnOverlap(AActor* OverlappedActor, AActor* OtherActor);
関数をデフォルトの実装にするには、接尾辞
_Implementation
を追加する必要があります。 BaseCoin.cppを開き、 OnOverlapをOnOverlap_Implementationに置き換え
OnOverlap_Implementation
。
void ABaseCoin::OnOverlap_Implementation(AActor* OverlappedActor, AActor* OtherActor)
子ブループリントが
OnOverlap()
実装しない場合、この実装が使用されます。
次のステップは、
OnOverlap()
を実装することです 。
ブループリントで実装を作成する
ブループリントでの実装では、
PlayCustomDeath()
を呼び出します。 このC ++関数は、コインの回転速度を上げます。 0.5秒後、コインはそれ自体を破壊します。
BlueprintsからC ++関数を呼び出すには、
BlueprintCallable
記述子を使用する必要があります。 BaseCoin.cppを閉じ、 BaseCoin.hを開きます 。
PlayCustomDeath()
を追加し
PlayCustomDeath()
。
UFUNCTION(BlueprintCallable)
Visual Studioをコンパイルして閉じます。 Unreal Engineに戻り、 BP_Coinを開きます 。 オーバーラップでオーバーライドし、次のスキームを作成します。
プレイヤーがコインに重ねられると、 Play Custom Deathが実行されます。
[ コンパイル]をクリックし、 BP_Coinを閉じます 。 [ 再生]をクリックしてコインを収集し、新しい実装をテストします。
GIF
次はどこに行きますか?
完成したプロジェクトはここからダウンロードできます。
ご覧のとおり、Unreal EngineでのC ++の操作は非常に簡単です。 C ++で既に何かを達成していますが、まだ学ぶべきことがたくさんあります! C ++を使用したトップダウンシューティングゲームの作成に関するEpicチュートリアルシリーズを検討することをお勧めします。
アンリアルエンジンを初めて使用する場合は、初心者向けの 10部構成のチュートリアルシリーズをご覧ください 。 このシリーズでは、ブループリント、マテリアル、パーティクルシステムなどのさまざまなシステムを紹介します。