跳到主内容
虚幻5
文章阅读

虚幻引擎中的游戏子系统,单例模式,线程

2025/12/16104 次阅读6 分钟

创建c++对象,继承GmaeInstanceSubsystem

我的游戏引擎实例,获取实例方法: UMyGameSubsystem* MySubsystem = GEngine->GetEngineSubsystem<UMyGameSubsystem>();

注意它有多个子系统,这里使用的是gameinstance,获取方式为const auto GameInstance = GetGameInstance(); ameInstance->GetSubsystem<UMyThreadGameInstanceSubsystem>()

还有其他一些子系统

  1. UGameInstanceSubsystem:游戏实例子系统,游戏中唯一。
  2. UWorldSubsystem:世界子系统,在每个UWorld中存在。
  3. ULocalPlayerSubsystem:每个本地玩家各自拥有一个。
  4. UEngineSubsystem:整个引擎中的唯一子系统,游戏生命周期内始终存在。

image.png

重写生命周期函数

.h


UCLASS()
class DEMO2_API UMyThreadGameInstanceSubsystem : public UGameInstanceSubsystem
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable,Blueprintable, Category = "StartThreadTask")
	void StartThreadTask();
private:
    //初始化执行
	virtual void Initialize(FSubsystemCollectionBase& Collection) override;
	//销毁时执行
    virtual void Deinitialize() override;
    //线程共享指针
	TSharedPtr<FMyTestThread> MyTestThread;
    //线程运行管理器
	FRunnableThread* RunnableThread;
};

.cpp



#include "MyThreadGameInstanceSubsystem.h"

void UMyThreadGameInstanceSubsystem::StartThreadTask()
{
	//创建一个线程
	UE_LOG(LogTemp, Warning, TEXT("StartThreadTask"));
	MyTestThread = MakeShared<FMyTestThread>("测试线程");
	RunnableThread = FRunnableThread::Create(MyTestThread.Get(),*MyTestThread->GetThreadName().ToString());
}

void UMyThreadGameInstanceSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
	UE_LOG(LogTemp,Log,TEXT("游戏实例初始化:UMyThreadGameInstanceSubsystem::Initialize"));
	Super::Initialize(Collection);
}

void UMyThreadGameInstanceSubsystem::Deinitialize()
{
	UE_LOG(LogTemp,Log,TEXT("游戏实例销毁:UMyThreadGameInstanceSubsystem::DeInitialize"));
	if(MyTestThread.IsValid())
	{
		MyTestThread->Stop();
	}
	if(RunnableThread)
	{
		RunnableThread->WaitForCompletion();
		delete RunnableThread;
		RunnableThread = nullptr;
	}
	Super::Deinitialize();
}

创建线程任务,注意对象名要F开头

.h


class DEMO2_API FMyTestThread final : public FRunnable
{
	
public:
	FMyTestThread();
	FMyTestThread(const FName& ThreadName);
	virtual ~FMyTestThread() override;
	//初始化,返回值表示是否初始化成功
	virtual bool Init() override;
	//运行任务,返回值0表示正常结束
	virtual uint32 Run() override;
	//任务停止
	virtual void Stop() override;
	//任务销毁退出
	virtual void Exit() override;
	//线程名称
	FName GetThreadName() const;

private:
	//属性,线程名
	FName ThreadName;
	//这是测试用,是否需要运行任务
	bool bIsRunning;
};

.cpp


FMyTestThread::FMyTestThread(): bIsRunning(false)
{
	UE_LOG(LogTemp, Warning, TEXT("FMyTestThread::FMyTestThread()"));
}

FMyTestThread::FMyTestThread(const FName& ThreadName): ThreadName(ThreadName), bIsRunning(false)
{
	UE_LOG(LogTemp, Warning, TEXT("Thread Created"));
}

FMyTestThread::~FMyTestThread()
{
	UE_LOG(LogTemp, Warning, TEXT("Thread Destroyed"));
}

bool FMyTestThread::Init()
{
	bIsRunning = true;
	return FRunnable::Init();
}


uint32 FMyTestThread::Run()
{
	while (bIsRunning)
	{
		FPlatformProcess::Sleep(3);
		UE_LOG(LogTemp, Warning, TEXT("Thread Running"));
	}
	return 0;
}

void FMyTestThread::Stop()
{
	UE_LOG(LogTemp, Warning, TEXT("FMyTestThread::Stop()"));
	bIsRunning = false;
	FRunnable::Stop();
}

void FMyTestThread::Exit()
{
	UE_LOG(LogTemp, Warning, TEXT("FMyTestThread::Exit"));
	FRunnable::Exit();
}

FName FMyTestThread::GetThreadName() const
{
	return ThreadName;
}

使用


///测试子系统
void AMyCharacter::StartTestThreadFunction()
{
	UE_LOG(LogTemp, Log, TEXT("测试游戏子系统."));
	if(const auto MyTestSubSystem = GetGameInstance()->GetSubsystem<UMyThreadGameInstanceSubsystem>())
	{
		MyTestSubSystem -> StartThreadTask();
	}
}

运行结果 image.png

返回顶部