簡単な2Dゲームを作ろう
2Dゲーム制作の練習シリーズです。
アンリアルエンジンで2Dゲーム制作方法をまとめていきます。
説明を省略したり、細かな数値設定などの説明をしない場合もありますので、ご参考程度で確認ください。
※作業環境:UEバージョン5.3.2 Windows11 VSCode
魔法を発射
発射する魔法の「Paper Flipbook」を作成する
発射する魔法のアニメーションを作成します。
「Paper Flipbook」の作成方法は、以下の記事を参考にしてください。
魔法のアクタークラスを作成する
発射する魔法のアクタクラスを作成します。
ファイル名は「Magic」にし、コードを編集していきます。
Magic.h
インクルードを追加します。
#include "GameFramework/Actor.h"
// 追加↓
#include "Components/SphereComponent.h"
#include "PaperFlipbookComponent.h"
// ここまで↑
「public:」内にコードを追加します。
UCLASS()
class PAPERGAME1_API AMagic : public AActor
{
GENERATED_BODY()
public:
// 追加↓
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
USphereComponent* SphereComp;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
UPaperFlipbookComponent* MagicFlipbook;
// ここまで↑
AMagic();
Magic.cpp
「AMagic::AMagic(){}」内にコードを追加します。
AMagic::AMagic()
{
PrimaryActorTick.bCanEverTick = true;
// 追加↓
SphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
SetRootComponent(SphereComp);
MagicFlipbook = CreateDefaultSubobject<UPaperFlipbookComponent>(TEXT("MagicFlipbook"));
MagicFlipbook->SetupAttachment(RootComponent);
// ここまで↑
}
保存して、リフレッシュ&コンパイルします。
魔法のブループリントを作成する
先ほど作成したクラスからブループリントを作成します。
新しいブループリントのクラスを「Magic」にして作成します。
ファイル名を「BP_Magic」にします。
ファイルを開いて、魔法のアニメーションを設定していきます。
「Components」の「Magic Flipbook (MagicFlipbook)」を選択します。
対応するコード
SphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
SetRootComponent(SphereComp);
MagicFlipbook = CreateDefaultSubobject<UPaperFlipbookComponent>(TEXT("MagicFlipbook"));
MagicFlipbook->SetupAttachment(RootComponent);
「Details」の「Sprite」の「Source Flipbook」に魔法アニメーションを設定します。
「Materials」の「Element 0」の設定は、「TranslucentUnlitSpriteMaterial」にします。
「Collision Presets」の設定を「NoCollision」にします。
「Translucency Sort Priority」の値を設定します。
ここらへんの設定は、以下の記事を参考にしてください。
「Components」の「Sphere Comp (Sphere Comp)」を選択します。
「Details」の「Shape」の「Sphere Radius」で大きさを調整します。
当たり判定のコリジョンになるので、絵を覆うぐらいの大きさにしています。
「Collidion Presets」は「OverlapAllDynamic」にします。
魔法を直進させる
魔法を動かすコードを追加していきます。
Magic.h
「public:」内にプロパティを追加します。
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
UPaperFlipbookComponent* MagicFlipbook;
// 追加↓
UPROPERTY(BlueprintReadWrite)
FVector2D MovementDirection;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float MovementSpeed = 300.0f;
// ここまで↑
Magic.cpp
「AMagic::AMagic(){}」内にコードを追加します。
AMagic::AMagic()
{
PrimaryActorTick.bCanEverTick = true;
SphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
SetRootComponent(SphereComp);
MagicFlipbook = CreateDefaultSubobject<UPaperFlipbookComponent>(TEXT("MagicFlipbook"));
MagicFlipbook->SetupAttachment(RootComponent);
// 追加↓
MovementDirection = FVector2D(1.0f, 0.0f);
// ここまで↑
}
void AMagic::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// 追加↓
FVector2D DistanceToMove = MovementDirection * MovementSpeed * DeltaTime; // 移動量を計算する
FVector CurrentLocation = GetActorLocation(); // アクターの位置を取得する
FVector NewLocation = CurrentLocation + FVector(DistanceToMove.X, 0.0f, DistanceToMove.Y); // 新しい位置を計算する
SetActorLocation(NewLocation); // 位置を更新する
// ここまで↑
}
保存して、コンパイルします。
ブループリントを設定していきます。
「BP_Magic」を開きます。
「Details」の「Magic」に「Movement Speed」項目が出来ています。
ここの値で、魔法の移動速度が変更できます。
対応するコード
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float MovementSpeed = 300.0f;
魔法の消滅時間を設定する
魔法を一定時間後に削除するコードを追加していきます。
Magic.h
インクルードを追加します。
#include "PaperFlipbookComponent.h"
// 追加↓
#include "Engine/TimerHandle.h"
// ここまで↑
「public:」内にプロパティを追加します。
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float MovementSpeed = 300.0f;
// 追加↓
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
bool IsLaunched = false;
FTimerHandle DeleteTimer;
// ここまで↑
関数も追加します。
virtual void Tick(float DeltaTime) override;
// 追加↓
void Launch(FVector2D Direction, float Speed);
void OnDeleteTimerTimeout();
// ここまで↑
Magic.cpp
先ほど作成した関数の定義を作成し、コードを追加します。
// 関数定義&編集
void AMagic::Launch(FVector2D Direction, float Speed)
{
if (IsLaunched) return; // 魔法を発射動作中ならここで処理終わり
IsLaunched = true; // 魔法発射動作中を示す
MovementDirection = Direction; // 発射向き
MovementSpeed = Speed; // 魔法速度
float DeleteTime = 10.0f; // 魔法消滅時間
GetWorldTimerManager().SetTimer(DeleteTimer, this, &AMagic::OnDeleteTimerTimeout, 1.0f, false, DeleteTime); // 指定時間に関数を呼び出す
}
// 関数定義&編集
void AMagic::OnDeleteTimerTimeout()
{
Destroy(); // 魔法を消す
}
「AMagic::Tick(){}」にコードを追加します。
void AMagic::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// 編集↓
if (IsLaunched) // 発射動作中にのみ処理する
{
FVector2D DistanceToMove = MovementDirection * MovementSpeed * DeltaTime;
FVector CurrentLocation = GetActorLocation();
FVector NewLocation = CurrentLocation + FVector(DistanceToMove.X, 0.0f, DistanceToMove.Y);
SetActorLocation(NewLocation);
}
// ここまで↑
}
ボタンを押して魔法を生成する
ボタンを押して魔法を生成できるようにしていきます。
PlayerCharacter.h
インクルードを追加します。
// 追加↓
#include "Engine/TimerHandle.h"
#include "Magic.h"
// ここまで↑
#include "PlayerCharacter.generated.h"
「public:」内にコードを追加します。
// 追加↓
UPROPERTY(EditDefaultsOnly)
TSubclassOf<AMagic> MagicActorToSpawn;
// ここまで↑
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float MovementSpeed = 1000.0f;
UPROPERTY(BlueprintReadWrite)
FVector2D MovementDirection;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
bool CanMove = true;
// 追加↓
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
bool CanShoot = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float ShootCooldownDurationInSecond = 0.3f;
FTimerHandle ShootCooldownTimer;
// ここまで↑
関数も追加します。
bool IsInMapBoundsHorizontal(float XPos);
bool IsInMapBoundsVertical(float ZPos);
// 追加↓
void OnShootCooldownTimerTimeout();
// ここまで↑
PlayerCharacter.cpp
先ほど作成した関数を定義します。
// 関数定義
void APlayerCharacter::OnShootCooldownTimerTimeout()
{
CanShoot = true; // 魔法発射できる状態を示す
}
魔法を発射する関数内を編集します。
void APlayerCharacter::Shoot(const FInputActionValue &Value)
{
// 編集↓
// GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Red, TEXT("Shoot")); // デバック用
if (CanShoot) // 魔法発射できる状態なら
{
CanShoot = false; // 出来ない状態にする
AMagic *Magic = GetWorld()->SpawnActor<AMagic>(MagicActorToSpawn, MagicSpawnPosition->GetComponentLocation(), FRotator(0.0f, 0.0f, 0.0f)); // 魔法をスポーンする
check(Magic); // クラッシュ対策
APlayerController* PlayerController = Cast<APlayerController>(Controller); // キャストする
check(PlayerController); // クラッシュ対策
FVector MouseWorldLocation, MouseWorldDirection; // 変数宣言
PlayerController->DeprojectMousePositionToWorld(MouseWorldLocation, MouseWorldDirection); // マウスの位置を取得する
FVector CurrentLocation = GetActorLocation(); // アクタの位置を取得する
FVector2D MagicDirection = FVector2D(MouseWorldLocation.X - CurrentLocation.X, MouseWorldLocation.Z - CurrentLocation.Z); // 魔法の発射方向を計算する
MagicDirection.Normalize(); // 正規化する
float MagicSpeed = Magic->MovementSpeed; // 魔法速度
Magic->Launch(MagicDirection, MagicSpeed); // 魔法を発射する
GetWorldTimerManager().SetTimer(ShootCooldownTimer, this, &APlayerCharacter::OnShootCooldownTimerTimeout, 1.0f, false, ShootCooldownDurationInSecond); // 指定時間に関数を呼び出す
}
// ここまで↑
}
保存して、リフレッシュ&コンパイルします。
プレイヤーのブループリントを編集する
コードの編集は完了したので、プレイヤーのブループリントを編集していきます。
「BP_PlayerCharacter」ファイルを開いて、「Details」の「Player Character」項目を確認します。
「Magic Actor to Spawn」に「BP_Magic」を設定します。
「Shoot Cooldown Duration in Second」の値を変更することで、魔法を発射する間隔を調整できます。
対応するコード
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float ShootCooldownDurationInSecond = 0.3f;
これで設定完了したので、テストプレイします。
ボタンを押すと矢印の方向に魔法が発射されるようになりました。
魔法の発射完了
今回はここまでです。
次回は「マウスカーソルの表示アイコンを変更する」です。
前後記事
前回の記事
・魔法発射アクションを実装する
次回の記事
・マウスカーソルの表示アイコンを変更する
他の記事を探す
他の記事も気になる方は、以下の記事の目次を確認ください。