アンリアルエンジンチュートリアル:C ++

画像






ブループリントは、Unreal Engine 4でゲームプレイを作成する非常に一般的な方法です。ただし、長い間プログラミングしてコードを好んでいるなら、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ファイルの名前とパスを指定できます。 NameBasePlayerに置き換え、 Create Classをクリックします









これにより、ファイルが作成され、プロジェクトがコンパイルされます。 コンパイル後、UnrealはVisual Studioを開きます。 BasePlayer.cppBasePlayer.hが開いいない場合は、ソリューションエクスプローラーに移動して開きます。 これらは、 Games \ CoinCollector \ Source \ CoinCollectorフォルダにあります









先に進む前に Unrealのリフレクションシステムについて知る必要があります 。 このシステムは、詳細パネルやガベージコレクションなど、エンジンのさまざまな部分を管理します。 C ++ Class Wizardを使用してクラスを作成すると、Unrealエンジンはタイトルに3行を追加します。



  1. #include "TypeName.generated.h"



  2. UCLASS()



  3. GENERATED_BODY()





Unrealエンジンは、クラスをリフレクションシステムから見えるようにするためにこれらの行を必要とします。 これが明確でない場合でも心配する必要はありません。 リフレクションシステムにより、ブループリントの関数や変数をエディターに展開するなどのことができることを知っておく必要があります。



また、クラスがABasePlayer



ではなくBasePlayer



と呼ばれていることにABasePlayer



かもしれませBasePlayer



。 タイプactorのクラスを作成するとき、Unrealはクラス名の前に接頭辞A (単語actorから)を付けます。 リフレクションシステムが機能するには、クラスに適切なプレフィックスが必要です。 Epic Code Standardのプレフィックスの詳細をご覧ください。



注:プレフィックスはエディターに表示されません。 たとえば、 ABasePlayer型の変数を作成する必要がある場合は、 BasePlayerを探す必要があります。


反射システムについて知る必要があるのはこれだけです。 次に、プレーヤーモデルとカメラを追加する必要があります。 これを行うには、 コンポーネントを使用します



コンポーネントを追加する



Pawnプレーヤーの場合、3つのコンポーネントを追加する必要があります。



  1. 静的メッシュ:プレイヤーモデルであるメッシュを選択できます
  2. スプリングアーム:このコンポーネントは、カメラの三脚として使用されます。 一端がメッシュに取り付けられ、カメラがもう一端に取り付けられます。
  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;
      
      





ここで使用される名前は、エディター内のコンポーネントの名前になります。 この場合、コンポーネントはMeshSpringArmおよび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







コンポーネントコードの完成後、コンパイルする必要があります。 次のコンパイル方法のいずれかを選択します。



  1. Visual Studioで、 ビルド\ソリューションのビルドを選択します
  2. アンリアルエンジンで、 ツールバーの [ コンパイル ]をクリックします


次に、使用するメッシュとスプリングレバーの回転を指定する必要があります。 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 MeshSM_Sphereに設定します。









次に、スプ​​リングレバーの回転と長さを設定する必要があります。 私たちのゲームは上面図になりますので、カメラはプレーヤーの上になければなりません。



SpringArmコンポーネントを選択し、 回転(0、 -50、0 )に設定します。 これにより、カメラがメッシュを見下ろすようにスプリングレバーが回転します。









スプリングレバーはメッシュの子であるため、ボールが回転し始めると回転し始めます。



GIF






これを修正するには、レバーの回転が絶対であることを確認する必要があります。 [ 回転]の横にある矢印をクリックして、[ ワールド]を選択します。



GIF






次に、 ターゲットアームの長さ1000に設定します 。 そのため、カメラをメッシュから1000ユニット離れたところに移動します。









次に、デフォルトのポーンクラスを設定して、ポーンを使用する必要があります。 [ コンパイル]をクリックして、エディターに戻ります。 World Settingsを開き、 Default PawnBP_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をオンにします。









[ コンパイル]をクリックし、[ 再生]をクリックします。 WAS、および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の値を設定する必要があります。 ツールバーの「 クラスのデフォルト」をクリックして、「詳細」パネルに移動します。 JumpImpulse100000に設定します。









[ コンパイル]をクリックし、 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部構成のチュートリアルシリーズをご覧ください 。 このシリーズでは、ブループリント、マテリアル、パーティクルシステムなどのさまざまなシステムを紹介します。



All Articles