【UnrealEngine】新規C++アクタを作成したときのコードを理解しよう
C++で新規アクタを作成してみたのですが、初心者の私にはそもそも初期コードが何を表しているのか理解ができないため、まずはデフォルトのコードが何をしているかを理解していきたいと思います。
右クリックからまずは新規C++クラスを作成してみます。クラス選択のポップアップが表示されたのですが、今回はアクタでやってみようと思います。クラスを作成したら少しロードが走りました。


今回はソースファイルの方を見ていきたいと思います。(ソースファイルは.cppの方です)

実際にクラス作成時にデフォルトで記述されているコードは下記になります。
デフォルトで作成されるコード
// ===========================
// ▼ここから
// ===========================
// Fill out your copyright notice in the Description page of Project Settings.
#include "TestActpr.h"
// Sets default values
ATestActpr::ATestActpr()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ATestActpr::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ATestActpr::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// ===========================
// ▲ここまで
// ===========================
◆見ていく前に!
・処理ブロック
{}は処理ブロックといい、C++のコードは処理ブロックの中に記述します。今回出てきませんが「if」や「for」も同じく処理ブロックに記述するようです。
・スコープ解決演算子(::)
C++では同じ名前の関数が複数存在することができるため、このクラスの関数だよ!と明示してあげる必要があります。そのため、「クラス::関数」のようにスコープ解決演算子を間に入れてコードを記述するようです。
・関数名()
()内は引数(パラメータ)を書く場所。
引数=関数に渡すデータ。
Void Tick(float DeltaTime)と記述されている場合、Delta Timeという値を受け取っている。ちなみに引数がない場合(()内が空の場合)何も受け取らない関数になる。
・;
文の終わり(処理の区切り)。1つの命令が終わったことをコンパイラに伝える記号。関数は処理ブロックで判別できるため「;」は必要なし。ヘッダーファイルでは処理ブロックの終わりにつける必要あっり。
{};=クラス定義終了を意味する。
◆見ていきましょう。
さて。それでは1つずつ見ていきましょうか!
// Fill out your copyright notice in the Description page of Project Settings.
こちらは「コメント」になり、「//」で始まる行はコンパイルに影響しない説明文になるようです。VBAなどでも以前ちょろっと勉強したのですが、コードは作成者本人が直ぐ分かるだけではなく、他の人が見たとき、その人にも分かりやすく記述することが大事になるため、説明メモを残すことは大事ですね。
ということでこの行は「プロジェクト設定の「説明」ページに著作権表示を記入してください」というメモです。
用途:メモ/説明/TODO

#include "TestActor.h"
こちらは、「TestActor.h」というヘッダーファイルの内容をこのファイルに読み込むというコードです。このヘッダーファイルは今回のアクタ作成時に作成されるものですね。
「#include” ファイル名.h”」で対象のヘッダーファイルを別のソースファイルなどでも対象のクラスを使用できそうですね。
◆イメージ
.cpp→.hを読み込む→クラスの構造が分かる
ATestActpr::ATestActpr()
これは「ATestActprクラスのコンストラクタ」と呼ばれるコードのようです。
「Actorが生成されたときの初期設定」を記述する場所のようです。
用途:初期値設定/コンポーネント生成/Tick設定など
ATestActpr=クラス名
ATestActpr()=関数名
➥コンストラクタのクラス名が同じ理由はC++のルールのようです。コードの構造としては「クラス名::関数名」となっているんですけど、コンストラクタだけは関数名=クラス名になるようです。
そのため、今回のコードは「ATestActorというクラスのATestActorという特別な関数」という意味
PrimaryActorTick.bCanEverTick = true;
こちらは「このActorはTickを使う」というコードです。分解すると下記のようになります。
◆PrimaryActorTick
➥ActorのTick設定を管理する構造体
◆bCanEverTick
➥「Tickを有効にするか」というフラグ
※TrueでTickを実行し、FalseでTickを無効にする。
void ATestActpr::BeginPlay()
{
Super::BeginPlay();
}
ゲーム開始時に呼ばれる関数。ブループリントのEventBegineplayノードと一緒ですね。ゲーム開始時に何かの処理を行いたいときはここにコードを記述する必要がありますね。
ちなみに「void」は戻り値なしを表してます。
「Super::BeginePlay」は親クラスのBeginePlayを実行という意味のようです。ActorはAActorというクラスを継承しているため、AActorのBeginePlayも実行する必要がありそのために記述している。
super:親クラスを指すコード
superの処理を記述しないとどうなる?と調べてみたところ、親クラスのBeginePlayが実行されないことによって、エンジン内部の処理が止まることがあるようです。そのため、基本的には「super::BeginePlay」を記述するのがルールだそうな。
つまり今回ActorはAActorを継承しているため、AActorの位置/回転/Tick/BeginePlayなどAActorの持つ機能をすべて使用することができる。
継承イメージ:AActorの能力+自分の能力
void ATestActpr::Tick(float DeltaTime)
こちらは毎フレーム呼ばれる関数になり、float DeltaTimeは前フレームからの経過時間です。ブループリントのEvent Tickと同じですね。
余談:60FPSであれば、DeltaTimeは約0.016秒になるそうです。
◆処理の流れについて
↓
② コンストラクタ
↓
③ BeginPlay
↓
④ Tick(毎フレーム)
◆YouTube
ゆうtuber・ゆうくん – YouTube
