UE5 C++ GameInstanceSubsystem 在学习

一.子系统概述

参考官方文档

虚幻引擎编程子系统 | 虚幻引擎 5.7 文档 | Epic Developer Community

游戏实例子系统 是子系统中的一种,目前用最多。编辑器的更多涉及到编辑器开发。

更多优点,去看大钊的文章。

二.子系统生命周期的优势 在关卡切换中

子系统几乎和引擎同步,所以游戏里喜欢把核心的跨关卡的数据放到 子系统里保存管理。一是方便获得,蓝图直接拿,C++有模块包个头就能用,爽,进而修改同步。二是 生命周期够长,即使是切换关卡后,也许物体没了,但子系统里的数据依然保留,方法指针等也会保留。也方便做后续的类似存档,读档。

以下是案例

在关卡蓝图里,调用子系统里的东西。

Map1 +11

Map2 +11

切换关卡,依然会执行。

三.子系统 与多播

通过子系统方便全局获得委托,并且进行绑定 和 呼叫执行。它俩简直绝配。

以下是案例。

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "GWXGameInstanceSubsystem.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FWXSubsystemLocation, FString ,InActionName, int32 ,InActionIndexTime);
/**
 * 
 */
//UGWXGameInstanceSubsystem* UGWXGameInstanceSubsystem::MySubsystem = nullptr;

UCLASS()
class THIRDLEARN_API UGWXGameInstanceSubsystem : public UGameInstanceSubsystem
{
	GENERATED_BODY()

public:

	virtual bool ShouldCreateSubsystem(UObject* Outer) const override;

	/** Implement this for initialization of instances of the system */
	virtual void Initialize(FSubsystemCollectionBase& Collection)override;

	/** Implement this for deinitialization of instances of the system */
	virtual void Deinitialize()override;

	UFUNCTION(BlueprintCallable)
	void CallLocation(FString InActionName,int32 InActionIndex);

	UFUNCTION(BlueprintCallable)
	UGWXGameInstanceSubsystem* GetGWXSubsystemself();

	UPROPERTY(BlueprintAssignable)
	FWXSubsystemLocation WXSubsystemLocationDelegate;

	void AddHealth(int num);

private:
	//static UGWXGameInstanceSubsystem* MySubsystem;
	int Health = 0;
};
cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.


#include "GWXGameInstanceSubsystem.h"



bool UGWXGameInstanceSubsystem::ShouldCreateSubsystem(UObject* Outer) const
{
	return true;
}

void UGWXGameInstanceSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);
	//MySubsystem = this;
}

void UGWXGameInstanceSubsystem::Deinitialize()
{
	//MySubsystem = nullptr;
	Super::Deinitialize();
}

void UGWXGameInstanceSubsystem::CallLocation(FString InActionName, int32 InActionIndex)
{
	WXSubsystemLocationDelegate.Broadcast(InActionName, InActionIndex);
}

UGWXGameInstanceSubsystem* UGWXGameInstanceSubsystem::GetGWXSubsystemself()
{
	//return MySubsystem;
	return nullptr;
}

void UGWXGameInstanceSubsystem::AddHealth(int num)
{
	Health += num;
}

在关卡蓝图中,通过子系统呼叫

在Actor里,通过子系统,绑定。很轻松就完成跨类委托

四.获得子系统的多种方式

A类获取,可以直接GetGameInstance->GetSubsystem获取

cpp 复制代码
void AGWXGamieInstance_TestActor::BeginPlay()
{
	Super::BeginPlay();
	UGameInstance* MyGameInstance = GetGameInstance();
	if (MyGameInstance)
	{
		UGWXGameInstanceSubsystem* MySimpleSubsystem = MyGameInstance->GetSubsystem<UGWXGameInstanceSubsystem>();
		MySimpleSubsystem->AddHealth(998);
	}
}

U类获取,需要获得World,再拿到GetGameInstance->GetSubsystem获取

cpp 复制代码
void AGWXGamieInstance_TestActor::ObjectGetSubsystem(const UObject* InWorldContextObject)
{
	if (InWorldContextObject && InWorldContextObject->GetWorld())
	{
		UGameInstance* MyGameInstace = InWorldContextObject->GetWorld()->GetGameInstance();
		if (MyGameInstace)
		{
			UGWXGameInstanceSubsystem* MySimpleSubsystem = MyGameInstace->GetSubsystem<UGWXGameInstanceSubsystem>();
			MySimpleSubsystem->AddHealth(2000);
		}
	}
}

传统static 获取,会有安全隐患

头文件

cpp 复制代码
	UFUNCTION(BlueprintCallable)
	static UGWXGameInstanceSubsystem* GetXGSubsystemMySelf();



private:
	int32 CurrentHealth = 100;
	bool bFirstTick = true;

	static UGWXGameInstanceSubsystem* MySubsystemPtr;

源文件,跟随生命周期赋值。

cpp 复制代码
#include "GWXGameInstanceSubsystem.h"

UGWXGameInstanceSubsystem* UGWXGameInstanceSubsystem::MySubsystemPtr = nullptr;

void UGWXGameInstanceSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);
	MySubsystemPtr = this;
}

void UGWXGameInstanceSubsystem::Deinitialize()
{
	MySubsystemPtr = nullptr;
	Super::Deinitialize();
}

UGWXGameInstanceSubsystem* UGWXGameInstanceSubsystem::GetXGSubsystemMySelf()
{
	return MySubsystemPtr;
}

其他类测试

复制代码
	UGWXGameInstanceSubsystem* MySimpleSubsystem = UGWXGameInstanceSubsystem::GetXGSubsystemMySelf();
	MySimpleSubsystem->AddHealth(666);

五.子系统的Tick

很简单在子系统里集成一个public FTickableGameObject类,重写Tick就行。还有些其它函数也可重写,如

cpp 复制代码
	virtual void Tick(float DeltaTime) override;

	virtual bool IsTickable() const override;

	virtual TStatId GetStatId() const override;

然后

cpp 复制代码
void UGWXGameInstanceSubsystem::Tick(float DeltaTime)  //无需super 虚方法
{
	UE_LOG(LogTemp,Warning,TEXT("12345"));
}

bool UGWXGameInstanceSubsystem::IsTickable() const
{
	return !IsTemplate();
}

TStatId UGWXGameInstanceSubsystem::GetStatId() const
{
	RETURN_QUICK_DECLARE_CYCLE_STAT(UGWXGameInstanceSubsystem, STATGROUP_Tickables);
}

就能每帧执行一次

相关推荐
念恒1230616 小时前
继承(下) (Inheritance)
c++
H Journey17 小时前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake
研究点啥好呢21 小时前
Github热门项目推荐 | 创建你的像素风格!
c++·python·node.js·github·开源软件
_dindong21 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
沫璃染墨21 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
6Hzlia1 天前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
计算机安禾1 天前
【数据结构与算法】第36篇:排序大总结:稳定性、时间复杂度与适用场景
c语言·数据结构·c++·算法·链表·线性回归·visual studio
unicrom_深圳市由你创科技1 天前
做虚拟示波器这种实时波形显示的上位机,用什么语言?
c++·python·c#
无限进步_1 天前
【C++】电话号码的字母组合:从有限处理到通用解法
开发语言·c++·ide·windows·git·github·visual studio
C++ 老炮儿的技术栈1 天前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt