六一的部落格


关关难过关关过,前路漫漫亦灿灿。



Subsystem


惯例,先上文档链接

5.3 - Programming Subsystems

可以看到,此处有四类编程子系统,另外,还有一个UWorldSubsystem,不知道为何没有归整到一块

子系统 Gameplay中相关
UEngineSubsystem UEngine Engine/Source/Runtime/Engine/Classes/Engine/Engine.h
UEditorSubsystem UEditorEngine Engine/Source/Editor/UnrealEd/Classes/Editor/EditorEngine.h
UGameInstanceSubsystem UGameInstance Engine/Source/Runtime/Engine/Classes/Engine/GameInstance.h
ULocalPlayerSubsystem LocalPlayer Engine/Source/Runtime/Engine/Classes/Engine/LocalPlayer.h
UWorldSubsystem UWorld Engine/Source/Runtime/Engine/Classes/Engine/World.h

由于我对子系统的了解实在太少,在此我只提两点:

  1. 这五个类的生存期并不相同,其能承载的信息因此也有所不同

  2. Gameplay中相关项在此前的开发中,略有接触,是具有全局指针指向的,即,在某个范畴内,可以认为有且仅有一个实例

    1UEngine *GEngine;
    2UEditorEngine *GEditor;
    3UGameInstance *GameInstance;
    4UWorld *World;
    5ULocalPlayer *LocalPlayer;

插件和子系统

就我目前对插件的使用,平常需要用到GameInstance的地方,全用的GameInstanceSubsystem。甚至,插件名称就是以GameInstanceSubsystem的名称刨去Subsystem指代命名的。

即,插件的主要功能,就是像GameInstance一样,在类似的处境中,履行自己的职责。

为插件添加UGameInstanceSubsystem的派生类,插件对外的功能,交由GISubsystem的派生类实现。

而插件中,有且只有一个UGameInstanceSubsystem的派生类对象。

可以粗糙地理解为,GameInstance于游戏,即UGameInstanceSubsystem派生类对象于插件。


例子

项目管理模块单独封装到插件ProjectManager,而插件里拥有UGameInstanceSubsystem的派生类UProjectManagerSubsystem。

插件对外的接口可以写在UProjectManagerSubsystem中,而项目管理相关的逻辑,由UProjectManagerSubsystem向内,细分后交由子逻辑处理。


为插件添加C++类 - UGameInstanceSubsystem的派生类

  1. 选择基类


  2. 添加到插件,命名为FirstGISubsystem



验证GISubsytem初始化

  • UGameInstanceSubsystem派生自USubsystem,初始化需覆写Initialize

    1virtual void Initialize(FSubsystemCollectionBase& Collection) {}
  • 添加Initialize

    public

    1virtual void Initialize(FSubsystemCollectionBase &Collection) override;
  • 在Initialize中打印日志

    1void UFirstGISubsystem::Initialize(FSubsystemCollectionBase &Collection)
    2{
    3    UE_LOG(LogTemp, Display, TEXT("[%s][%d]FirstGISubsystem"), *FString(__FUNCTION__), __LINE__);
    4}

输出如下



GISubsystem的获取

  1. 使用虚幻提供的子系统蓝图函数库

    1#include "Subsystems/SubsystemBlueprintLibrary.h"
    2
    3UGameInstanceSubsystem *GISubsystem = USubsystemBlueprintLibrary::GetGameInstanceSubsystem(GWorld, UFirstGISubsystem::StaticClass());
    4UFirstGISubsystem *FirstGISubsystem = Cast<UFirstGISubsystem>(GISubsystem);
  2. 通过GameInstance获取

    1UFirstGISubsystem *FirstGISubsystem = GetGameInstance()->GetSubsystem<UFirstGISubsystem>();

参考

知乎 - 大钊 - Subsystems

知乎 - 大钊 - Game Features

UE4中的Subsystem

【UE4 C++】编程子系统 Subsystem


虚幻编程子系统 - GameInstanceSubsystem


Subsystem


惯例,先上文档链接

5.3 - Programming Subsystems

可以看到,此处有四类编程子系统,另外,还有一个UWorldSubsystem,不知道为何没有归整到一块

子系统 Gameplay中相关
UEngineSubsystem UEngine Engine/Source/Runtime/Engine/Classes/Engine/Engine.h
UEditorSubsystem UEditorEngine Engine/Source/Editor/UnrealEd/Classes/Editor/EditorEngine.h
UGameInstanceSubsystem UGameInstance Engine/Source/Runtime/Engine/Classes/Engine/GameInstance.h
ULocalPlayerSubsystem LocalPlayer Engine/Source/Runtime/Engine/Classes/Engine/LocalPlayer.h
UWorldSubsystem UWorld Engine/Source/Runtime/Engine/Classes/Engine/World.h

由于我对子系统的了解实在太少,在此我只提两点:

  1. 这五个类的生存期并不相同,其能承载的信息因此也有所不同

  2. Gameplay中相关项在此前的开发中,略有接触,是具有全局指针指向的,即,在某个范畴内,可以认为有且仅有一个实例

    1UEngine *GEngine;
    2UEditorEngine *GEditor;
    3UGameInstance *GameInstance;
    4UWorld *World;
    5ULocalPlayer *LocalPlayer;

插件和子系统

就我目前对插件的使用,平常需要用到GameInstance的地方,全用的GameInstanceSubsystem。甚至,插件名称就是以GameInstanceSubsystem的名称刨去Subsystem指代命名的。

即,插件的主要功能,就是像GameInstance一样,在类似的处境中,履行自己的职责。

为插件添加UGameInstanceSubsystem的派生类,插件对外的功能,交由GISubsystem的派生类实现。

而插件中,有且只有一个UGameInstanceSubsystem的派生类对象。

可以粗糙地理解为,GameInstance于游戏,即UGameInstanceSubsystem派生类对象于插件。


例子

项目管理模块单独封装到插件ProjectManager,而插件里拥有UGameInstanceSubsystem的派生类UProjectManagerSubsystem。

插件对外的接口可以写在UProjectManagerSubsystem中,而项目管理相关的逻辑,由UProjectManagerSubsystem向内,细分后交由子逻辑处理。


为插件添加C++类 - UGameInstanceSubsystem的派生类

  1. 选择基类


  2. 添加到插件,命名为FirstGISubsystem



验证GISubsytem初始化

  • UGameInstanceSubsystem派生自USubsystem,初始化需覆写Initialize

    1virtual void Initialize(FSubsystemCollectionBase& Collection) {}
  • 添加Initialize

    public

    1virtual void Initialize(FSubsystemCollectionBase &Collection) override;
  • 在Initialize中打印日志

    1void UFirstGISubsystem::Initialize(FSubsystemCollectionBase &Collection)
    2{
    3    UE_LOG(LogTemp, Display, TEXT("[%s][%d]FirstGISubsystem"), *FString(__FUNCTION__), __LINE__);
    4}

输出如下



GISubsystem的获取

  1. 使用虚幻提供的子系统蓝图函数库

    1#include "Subsystems/SubsystemBlueprintLibrary.h"
    2
    3UGameInstanceSubsystem *GISubsystem = USubsystemBlueprintLibrary::GetGameInstanceSubsystem(GWorld, UFirstGISubsystem::StaticClass());
    4UFirstGISubsystem *FirstGISubsystem = Cast<UFirstGISubsystem>(GISubsystem);
  2. 通过GameInstance获取

    1UFirstGISubsystem *FirstGISubsystem = GetGameInstance()->GetSubsystem<UFirstGISubsystem>();

参考

知乎 - 大钊 - Subsystems

知乎 - 大钊 - Game Features

UE4中的Subsystem

【UE4 C++】编程子系统 Subsystem