UE中实现单例有多种方式,如古早的静态变量,或是SubSystem。而对于Module(如自定义C++插件),可以使用FModuleManager的单例接口,提供模块级别的单例使用。
以UE5.7 C++项目为例,新建C++ Plugins项目Test01以测试。

测试模块命名为Test01,代码:
.h
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleInterface.h"
#include "Modules/ModuleManager.h"
DECLARE_LOG_CATEGORY_EXTERN(LogTest01, Log, All);
/**
* Test01 module singleton.
* Access the unique instance via FTest01Module::Get().
*/
class FTest01Module : public IModuleInterface
{
public:
static FTest01Module& Get()
{
return FModuleManager::LoadModuleChecked<FTest01Module>("Test01");
}
void SayHello();
int32 GetCallCount() const { return CallCount; }
virtual void StartupModule() override;
virtual void ShutdownModule() override;
private:
int32 CallCount = 0;
};
.cpp
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Test01.h"
DEFINE_LOG_CATEGORY(LogTest01);
void FTest01Module::StartupModule()
{
UE_LOG(LogTest01, Log, TEXT("Test01 module loaded (this=%p)"), this);
}
void FTest01Module::ShutdownModule()
{
UE_LOG(LogTest01, Log, TEXT("Test01 module unloaded"));
}
void FTest01Module::SayHello()
{
++CallCount;
UE_LOG(LogTest01, Log, TEXT("Hello World from Test01 module singleton! (CallCount=%d, this=%p)"), CallCount, this);
}
IMPLEMENT_MODULE(FTest01Module, Test01);
重要接口是FModuleManager.LoadModuleChecked,因为参数需要填入模块名称,所以不支持对任意类进行获得单例实例操作。
static FTest01Module& Get()
{
return FModuleManager::LoadModuleChecked<FTest01Module>("Test01");
}
关联下UE蓝图函数库
void UTest01BPLibrary::TestSingletonHelloWorld()
{
FTest01Module::Get().SayHello();
}
进游戏测试下,Log已正确触发:


2931

被折叠的 条评论
为什么被折叠?



