0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【UE5/C++】UObject クラスを継承してシングルトンクラスを作る

Last updated at Posted at 2024-11-27

はじめに

常に同じ変数などを参照するために、シングルトンなクラスを作りたかったため作ってみた。

シングルトンクラスを作る

TestSingleton クラスをシングルトンクラスとして扱う。自身のインスタンスを static で保持、コンストラクタを private にして外部からインスタンス化できなくする。

TestSingleton.h
#pragma once

#include "CoreMinimal.h"
#include "Test.generated.h"

UCLASS()
class TESTGAME_API TestSingleton : public UObject
{
	GENERATED_BODY()

public:
	// シングルトンオブジェクトを取得するため static メソッドにする
	static UTestSingleton* GetInstance();

private:
	// シングルトンにするのでコンストラクタは private にする
	UTestSingleton();

	// インスタンスを private static で保持する
	static UTestSingleton* Instance;

	int32 Count;

public:
	void IncreaseCount();
};
Test.cpp
#include "Test.h"

// 自身のインスタンスを nullptr で初期化
UTestSingleton* UTestSingleton::Instance = nullptr;

UTestSingleton::UTestSingleton()
{
	Count = 0;
}

UTestSingleton* UTestSingleton::GetInstance()
{
    // インスタンスがなければ作り、あればそれを返す
	if (Instance == nullptr)
	{
		Instance = NewObject<UTestSingleton>();
		Instance->AddToRoot(); // ガベージコレクション対策
	}
	return Instance;
}

int32 UTestSingleton::IncreaseCount()
{
	Count++;
}

使う側のクラス

このクラスがインスタンス化されたときに、シングルトンクラスのインスタンスを static メソッドにアクセスして取得する。
注意点として UPROPERTY() こいつを忘れるとガベージコレクションに回収されて使えなくなる可能性があるらしい。
Rider 上でこんな警告を確認した → Object member 'TestSingleton' can be destroyed during garbage collection, resulting in a stale pointer

Test.h
#pragma once

#include "CoreMinimal.h"
#include "TestSingleton.h"
#include "Test.generated.h"

UCLASS()
class TESTGAME_API Test : public AActor
{
	GENERATED_BODY()

public:
	ATest();

protected:
	virtual void BeginPlay() override;

public:
	virtual void Tick(float DeltaTime) override;

private:
	UPROPERTY()
	UTestSingleton* TestSingleton;
};
Test.cpp
#include "Test.h"

ATest::ATest()
{
    PrimaryActorTick.bCanEverTick = true;

    // シングルトンなインスタンスを取得している
    TestSingleton = ATestSingleton::GetInstance(); // インスタンスの取得
}

void ATest::BeginPlay()
{
    Super::BeginPlay();
}

void ATest::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
    
    TestSingleton->IncreaseCount();
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?