Подсистемы UE
Предисловие
Содержание статьи взято из Подсистемы . Эта статья представляет собой просто облачную заметку. Чтобы узнать, прочтите оригинальную статью.
определение:
Подсистемы — это платформа для определения классов, экземпляры которых автоматически создаются и выпускаются. Эта структура позволяет вам определять подклассы, выбирая одну из 5 категорий (может быть определена только в C++):
- Подсистема UEngine
- UEngine* GEngine
- Подсистема UEditor
- UEditorEngine* GEditor
- Подсистема UGameInstanceSubsystem
- UGameInstance* GameInstance
- UWorldПодсистема
- UМир* Мир
- Подсистема ULocalPlayerSubsystem
- ULocalPlayer* LocalPlayer
преимущество
- автоматическое создание экземпляров
- Эти классы UMyXXXSubsystem будут создавать объекты в нужное время, а затем выпускать их в нужное время.Этот процесс автоматизирован. Нет необходимости создавать код вручную. Нет необходимости самостоятельно определять переменные, в Subsystems уже определен удобный и дружественный интерфейс доступа.
- Жизненный цикл хостинга
- В зависимости от выбранного вами родительского класса движок будет реализовывать разные жизненные циклы для созданной подсистемы. Поэтому в официальных документах эти пять родительских классов будут называться пятью разными жизненными циклами. В зависимости от жизненного цикла, который вы выберете,
Initialize()
онDeinitialize()
будет автоматически вызываться в подходящее время. Тип Subystem также может автоматически создавать несколько экземпляров по мере необходимости. Вам не нужно беспокоиться о сложной логике в них.
- В зависимости от выбранного вами родительского класса движок будет реализовывать разные жизненные циклы для созданной подсистемы. Поэтому в официальных документах эти пять родительских классов будут называться пятью разными жизненными циклами. В зависимости от жизненного цикла, который вы выберете,
использовать:
Перегруженные функции
virtual bool ShouldCreateSubsystem(UObject* Outer) const override { return true; }
virtual void Initialize(FSubsystemCollectionBase& Collection)override;
virtual void Deinitialize()override;
Доступ к С++
//UMyEngineSubsystem获取
UMyEngineSubsystem* MySubsystem = GEngine->GetEngineSubsystem<UMyEngineSubsystem>();
//UMyEditorSubsystem的获取
UMyEditorSubsystem* MySubsystem = GEditor->GetEditorSubsystem<UMyEditorSubsystem>();
//UMyGameInstanceSubsystem的获取
UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(...);
UMyGameInstanceSubsystem* MySubsystem = GameInstance->GetSubsystem<UMyGameInstanceSubsystem>();
//UMyWorldSubsystem的获取
UWorld* World=MyActor->GetWorld(); //world用各种方式也都可以
UMyWorldSubsystem* MySubsystem=World->GetSubsystem<UMyWorldSubsystem>();
//UMyLocalPlayerSubsystem的获取
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player)
UMyLocalPlayerSubsystem * MySubsystem = LocalPlayer->GetSubsystem<UMyLocalPlayerSubsystem>();
//我省略了一些宏标记和注释,因为函数名字是不言自明的。
UCLASS()
class ENGINE_API USubsystemBlueprintLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
static UEngineSubsystem* GetEngineSubsystem(TSubclassOf<UEngineSubsystem> Class);
static UGameInstanceSubsystem* GetGameInstanceSubsystem(UObject* ContextObject, TSubclassOf<UGameInstanceSubsystem> Class);
static ULocalPlayerSubsystem* GetLocalPlayerSubsystem(UObject* ContextObject, TSubclassOf<ULocalPlayerSubsystem> Class);
static UWorldSubsystem* GetWorldSubsystem(UObject* ContextObject, TSubclassOf<UWorldSubsystem> Class);
static ULocalPlayerSubsystem* GetLocalPlayerSubSystemFromPlayerController(APlayerController* PlayerController, TSubclassOf<ULocalPlayerSubsystem> Class);
};
жизненный цикл:
- UGameInstanceSubsystem: количество 1. Зависит от жизненного цикла GameInstance, он создается в начале игры и уничтожается при выходе из игры. Под игрой здесь подразумевается, работает ли она в режиме Runtime или PIE. В игре можно создать несколько переключателей мира.
- UWorldSubsystem: количество может быть >1. Зависит от UWorld, обычно жизненный цикл такой же, как у GameMode, он будет уничтожаться и создаваться при переключении уровней. Но сцена во вьюпорте в режиме редактора на самом деле является Миром, и ее жизненный цикл такой же, как и у Редактора.
- UEditorSubsystem: существует только в режиме редактора, количество 1. Зависит от GEditor, он создается при запуске редактора и уничтожается при выходе из редактора.
- UEngineSubsystem: зависит от GEngine, режим редактора или среды выполнения глобально уникален. Он создается при запуске процесса и уничтожается при выходе из процесса.
- ULocalPlayerSubsystem: число зависит от количества LocalPlayer. Зависит от ULocalPlayer, обычно жизненный цикл соответствует GameInstance.
UEngineSubsystem и UEditorSubsystem принадлежат UDynamicSubsystem и могут создаваться и уничтожаться в зависимости от загрузки и выпуска модуля.
Применение:
1. Траверс
const TArray<USourceControlSubsystem*>& systems= GEngine->GetEngineSubsystemArray<USourceControlSubsystem>();
2. Наследование чертежей
C++ создает абстрактный базовый класс -> проект наследует абстрактный базовый класс -> явно загружает базовый класс проекта
UCLASS(abstract, Blueprintable, BlueprintType)
class HELLO_API UMyGameInstanceSubsystemBase : public UGameInstanceSubsystem
{
}
UObject* bpAsset = LoadObject<UObject>(NULL, TEXT("/Game/BP_MyGameInstanceSubsystem.BP_MyGameInstanceSubsystem_C"));
3. Несколько подсистем одного и того же BaseType могут определять порядок зависимости.
Система миссий основана на системе подсчета очков.
void UMyTaskSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
//初始化依赖项
Collection.InitializeDependency(UMyScoreSubsystem::StaticClass());
//获取
UMyScoreSubsystem* ss=((FSubsystemCollection<UGameInstanceSubsystem>&)Collection).GetSubsystem<UMyScoreSubsystem>(UMyScoreSubsystem::StaticClass());
}
4. Отметьте галочкой
UCLASS()
class HELLO_API UMyTickSubsystem : public UGameInstanceSubsystem,public FTickableGameObject
{
GENERATED_BODY()
public:
virtual void Tick(float DeltaTime) override;
virtual bool IsTickable() const override { return !IsTemplate(); }//不是CDO才Tick
virtual TStatId GetStatId() const override{RETURN_QUICK_DECLARE_CYCLE_STAT(UMyScoreSubsystem, STATGROUP_Tickables);}
};