はじめに
常に同じ変数などを参照するために、シングルトンなクラスを作りたかったため作ってみた。
シングルトンクラスを作る
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();
}