UE5.3を使用したゲーム制作備忘録を作成中!

モバイル向けゲームを作るため日々奮闘中!
同じ悩みを持つ人たちの、解決の糸口になれば幸いです。

詳細はこちら
PR
スポンサーリンク

Unreal Engine コツコツ自習_ゲームのリセットを実装する【2Dゲーム】

UEコツコツ自習シリーズ
スポンサーリンク

簡単な2Dゲームを作ろう

2Dゲーム制作の練習シリーズです。

アンリアルエンジンで2Dゲーム制作方法をまとめていきます。

説明を省略したり、細かな数値設定などの説明をしない場合もありますので、ご参考程度で確認ください。

※作業環境:UEバージョン5.3.2 Windows11 VSCode

ゲームのリセットを実装

前回作成した障害物に衝突したときにゲームを初めからにしてみます。

ゲームモードクラスのコードを編集する

VSCodeエディタを開いて、ゲームモードクラスを編集していきます。

GM_MyGameMode.h

インクルードを追加します。

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
// 追加↓
#include "Engine/TimerHandle.h"
// ここまで↑
#include "GM_MyGameMode.generated.h"

「class PAPERGAME1_API AGM_MyGameMode : public AGameModeBase{}」内にコードを追加します。

UCLASS()
class PAPERGAME1_API AGM_MyGameMode : public AGameModeBase
{
	GENERATED_BODY()
// 追加↓
public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float LoseResetTime = 1.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float WinResetTime = 3.0f;
	
	FTimerHandle ResetGameTimer;

	void ResetLevel(bool IsWin);
	void OnResetGameTimerTimeout();
// ここまで↑
};

GM_MyGameMode.cpp

インクルードを追加します。

#include "GM_MyGameMode.h"
// 追加↓
#include "Kismet/GameplayStatics.h"
// ここまで↑

ヘッダーファイルで追加した2つの関数定義を作成します。
・void ResetLevel(bool IsWin)
・void OnResetGameTimerTimeout()

// 関数定義
void AGM_MyGameMode::ResetLevel(bool IsWin)
{
    // 追加↓
    float ResetTime = LoseResetTime; // 負けた場合の時間をセットする
    if (IsWin) // もし勝ったら
    {
        ResetTime = WinResetTime; // 勝利したときの時間をセットする
    }
    GetWorldTimerManager().SetTimer(ResetGameTimer, this, &AGM_MyGameMode::OnResetGameTimerTimeout, 1.0f, false, ResetTime); // セットした時間経過後に関数を呼び出す
    // ここまで↑
}

// 関数定義
void AGM_MyGameMode::OnResetGameTimerTimeout()
{
    // 追加↓
    UGameplayStatics::OpenLevel(GetWorld(), FName("MainLevel")); // 指定したレベルを呼び出す
    // ここまで↑
}

今回は勝ち負けを設定しませんが、勝ち負けを追加する場合のコードにしています。

呼び出すレベルは現在プレイしているステージです。

なので、レベルを呼び出すとゲームが初めからになります。

プレイしてみると、プレイヤーの位置はプレイ初めの位置に戻る感じになると思います。

障害物に接触したときの処理を編集する

次に障害物と接触したときに、先ほど作成した処理を呼び出すように編集します。

Obstacle.h

インクルードを追加します。

#include "PaperSpriteComponent.h"
// 追加↓
#include "GM_MyGameMode.h"
// ここまで↑
#include "Obstacle.generated.h"

「public:」内にコードを追加します。

UCLASS()
class PAPERGAME1_API AObstacle : public AActor
{
	GENERATED_BODY()
	
public:	
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	UCapsuleComponent* CapsuleComp;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	UPaperSpriteComponent* ObstaclSprite;

// 追加↓
	AGM_MyGameMode* MyGameMode;
// ここまで↑

	AObstacle();

Obstacle.cpp

インクルードを追加します。

#include "Obstacle.h"
// 追加↓
#include "Kismet/GameplayStatics.h"
// ここまで↑
#include "PlayerCharacter.h"

void AObstacle::BeginPlay(){}にコードを追加します。

void AObstacle::BeginPlay()
{
	Super::BeginPlay();

	CapsuleComp->OnComponentBeginOverlap.AddDynamic(this, &AObstacle::OverlapBegin);

// 追加↓
	AGameModeBase* GameMode = UGameplayStatics::GetGameMode(GetWorld()); // ゲームモードを取得する
	MyGameMode = Cast<AGM_MyGameMode>(GameMode); // キャストする
// ここまで↑

}

プレイヤーが衝突したらレベルを呼び出す処理を追加します。

void AObstacle::OverlapBegin(UPrimitiveComponent *OverlappedComponent, AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex, bool FromSweep, const FHitResult &SweepResult)
{
	APlayerCharacter* Player = Cast<APlayerCharacter>(OtherActor);
	if (Player)
	{
		// GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::White, TEXT("Overlapped with player!")); // デバック用
		if (Player->CanMove)
		{
			Player->CanMove = false;
// 追加↓
			MyGameMode->ResetLevel(false); // レベルを呼び出す
// ここまで↑
		}
	}
}

保存して、リフレッシュ&コンパイルをします。

正常に終了したら、実際にプレイして確かめます。

プレイヤーが障害物に触れると、少し時間をおいてからプレイヤーの位置が初めの位置に戻ります。

レベルを呼び出すと、データを読み込み直すのでゲームが初めからになります。

ゴールを設定したり、呼び出すレベルを変えたりすることでゲームっぽくなると思います。

アレンジしてみてください。

ゲームのリセット実装完了

今回はここまでです。

次回は「BGMを実装する」です。

前後記事

次回の記事
・BGMを実装する

他の記事を探す

他の記事も気になる方は、以下の記事の目次を確認ください。

タイトルとURLをコピーしました