目录
了解生命周期
为什么用他,简单讲解?
SubSystems创建和使用
创建SubSystems中的UGamelnstanceSubsystem类:
写基本的3个函数:
在蓝图中的样子:
创建SubSystems中的UEditorSubsystem类:
SubSystem是什么就不多说了,可以看看大钊的相关文章:
《InsideUE4》GamePlay架构(十一)Subsystems - 知乎 (zhihu.com)
这篇文章很好的讲解了关于SubSystems的相关内容,我也就讲讲应该需要知道的重点和怎么做:
第一步是了解SubSystems中提供框架中的5个生命周期:
UEngineSubsystem
代表引擎,数量1。Editor或Runtime模式都是全局唯—,从进程启动开始创建,进程退出时销毁。
UEditorSubsystem
代表编辑器,数量为1。顾名思义,只在编辑器下存在且全局唯—,从编辑器启动开始创建,到编辑器退出时销毁。
UGamelnstanceSubsystem
代表—场游戏,数量1。从游戏的启动开始创建,游戏退出时销毁。这里的—场游戏指的是Runtimea或PIE模式的运行的都算,—场游戏里可能会创建多个World【或者叫Level】切换。
UWorldSubsystem
代表—个世界,数量可能>1。其生命周期跟归属的World【或者叫Level】有关
代表本地玩家,数量可能>1。UE支持本地分屏多玩家类型的游戏,但往往最常见的是就只有一个。LocalPlayer虽然往往跟Playercontroller—
ULocalPlayerSubsystem
起访问,但是其生命周期其实是跟UGamelnstance—起的(默认—开始的时候就创建好—定数量的本地玩家),或者更准确的说是跟LocalPlayer的具体数量挂钩(当然你也可以运行时动态调用AddLocalPlayer)。
不仅仅是因为其中的5个生命周期,更是因为其的可移植性强,并且可以解放你的双手,无需时时刻刻考虑内存问题:类似于在哪里new和在哪里delete的问题。
避免某个如pawn类,gameinstance类过于臃肿。
方便团队合作不同模块,方便不同插件的引用。
更好的封装,避免了数据污染。
甚至可以最为简单粗暴的将里面的内容复制粘贴到其他项目中。
那么在了解了生命周期之后,想必如果想要做一个计分系统之类的东西,大家都应该知道要在哪个生命周期制作了把。
这里我就做继承于UGamelnstanceSubsystem的类了。
正常c++创建搜索:
这个命名其实可以取各个不同的系统,因为它的可移植性,所以这个系统模块是很好让其他人进行分工合作的,比如计分系统写一个这个,血量系统写一个这个。
然后我们可以看见这个空空如也的类。
对此我们需要写3个函数。
头文件:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "LJGameInstanceSubsystem.generated.h"
/**
*
*/
UCLASS()
class UEDSTUDY_API ULJGameInstanceSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
//是否创建这个子系统
virtual bool ShouldCreateSubsystem(UObject* Outer) const;
//初始化
virtual void Initialize(FSubsystemCollectionBase& Collection);
//销毁
virtual void Deinitialize();
};
cpp文件:
// Fill out your copyright notice in the Description page of Project Settings.
#include "LJGameInstanceSubsystem.h"
bool ULJGameInstanceSubsystem::ShouldCreateSubsystem(UObject* Outer) const
{
Super::ShouldCreateSubsystem(Outer);
return true;
}
void ULJGameInstanceSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
//可以对一些资源进行初始化
Super::Initialize(Collection);
}
void ULJGameInstanceSubsystem::Deinitialize()
{
//这里对资源进行卸载
Super::Deinitialize();
}
然后我们在创建一个简单的变量,和一个函数。
然后在蓝图中可以看见:
如果想要在蓝图中创建,就需要加一些东西:
详情可以看这个:
UE4/5关于c++中的actor组件无法创建蓝图类的解决方法_多方通行8的博客-CSDN博客
UE4/5C++之关于UCLASS()的说明符和元数据修饰符_多方通行8的博客-CSDN博客
然后就可以创建了:
和之前创建UGameInstanceSubsystem一样,对此我就直接在项目中直接创建了:
然后这样:
头文件:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "EditorSubsystem.h"
#include "LJEditorSubsystem.generated.h"
/**
*
*/
UCLASS(Blueprintable)
class UEDSTUDY_API ULJEditorSubsystem : public UEditorSubsystem
{
GENERATED_BODY()
public:
//是否创建这个子系统
virtual bool ShouldCreateSubsystem(UObject* Outer) const;
//初始化
virtual void Initialize(FSubsystemCollectionBase& Collection);
//销毁
virtual void Deinitialize();
};
cpp文件:
// Fill out your copyright notice in the Description page of Project Settings.
#include "LJEditorSubsystem.h"
bool ULJEditorSubsystem::ShouldCreateSubsystem(UObject* Outer) const
{
Super::ShouldCreateSubsystem(Outer);
return true;
}
void ULJEditorSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
//可以对一些资源进行初始化
Super::Initialize(Collection);
}
void ULJEditorSubsystem::Deinitialize()
{
//这里对资源进行卸载
Super::Deinitialize();
}
创建这个之后,我们需要注意的是需要在项目的bulid.cs中输入:
"EditorSubsystem"这个模块才能编译成功【而我的UE5可以不输入这个模块就成功了,不知道是什么原因,但我还是写出来,以防止各位可能出现相关的问题】
然后在蓝图中的这里看到:
因为都是编辑器的生命周期,所以在其他的蓝图里面只能进行cast to 某个类,而无法直接看到这个,所以我们才能在编辑器工具中看到:
不论是编辑器工具控件或者是编辑器工具蓝图都可以看见: