ChatGPTにUE5のSubSystemについて聞いた


メニューの状態などを管理するシステムを作り、いつどのレベルからも状態を保持したクラスとして呼び出せるようにしたいのですが、サブシステムというもので可能ですか?


はい、Unreal Engine 5のサブシステムを使用して、メニューの状態などのグローバルな状態を管理し、いつでもどのレベルからでもアクセスできるようにすることは可能です。サブシステムを利用することで、エンジン全般にわたる状態を便利に管理でき、シングルトンのように動作するため非常に使いやすいです。

以下は、UE5のサブシステムを使用してメニュー状態を管理するための手順です。

### ステップ 1: ブループリントによるサブシステムの作成
#### 1.1 サブシステムクラスの作成
1. **Content Browser**で右クリックし、**Blueprint Class**を選択します。
2. **検索バー**に「Subsystem」と入力し、**Game Instance Subsystem**を選択します。
3. 名前を「MenuSubsystem」にします。
#### 1.2 サブシステムのプロパティと関数の追加
1. **MenuSubsystem**をダブルクリックして開きます。
2. メニュー状態を保持するためのブール変数などを追加します。例えば、`bIsMenuOpen` というブール変数を追加します。
3. メニュー状態の設定・取得用の関数を追加します。
   - SetMenuOpen(bool bOpen) のような関数を作成し、`bIsMenuOpen` 変数を設定します。
   - IsMenuOpen() のような関数を作成し、`bIsMenuOpen` 変数を返します。

### ステップ 2: ゲームインスタンスでサブシステムを有効化
1. サブシステムを使用するために、ゲームインスタンスクラスを設定します。
2. プロジェクトのデフォルトゲームインスタンスクラスを変更するには、**Edit > Project Settings**を開き、**Maps & Modes** の**Default Game Instance**を設定します(必要に応じて、新しいゲームインスタンスを作成します)。
3. ゲームインスタンスにサブシステムが自動的にロードされます。

### ステップ 3: サブシステムを利用してメニュー状態を管理
ここでは、プレイヤーキャラクターやウィジェットからサブシステムを呼び出す方法を示します。
#### 3.1 プレイヤーキャラクターでの使用方法
1. プレイヤーキャラクターのブループリントを開きます。
2. メニューのトグル処理にサブシステムを使用します。
BP
Event IA_ToggleMenu
   ↓
Get Game Instance
   ↓
Cast to MyGameInstance (ゲームインスタンス)
   ↓
Get Subsystem (MenuSubsystem)
   ↓
IsMenuOpen
   ↓
Branch (IsMenuOpen?)
   ↙          ↘
True        False
↓              ↓
SetMenuOpen(False)    SetMenuOpen(True)
Remove Mapping Context (MenuInputMapping)    Add Mapping Context (MenuInputMapping)
Add Mapping Context (PlayerInputMapping)    Remove Mapping Context (PlayerInputMapping)
Set Show Mouse Cursor (False)    Set Show Mouse Cursor (True)
#### 3.2 メニューウィジェットでの使用方法
1. メニューウィジェットのブループリントを開きます。
2. Construct イベントで、メニューの開閉状態を初期化する際にサブシステムを使用します。
BP
Event Construct
   ↓
Get Game Instance
   ↓
Cast to MyGameInstance (ゲームインスタンス)
   ↓
Get Subsystem (MenuSubsystem)
   ↓
IsMenuOpen
   ↓
Branch (IsMenuOpen?)
   ↙          ↘
True        False
↓               ↓
Show Menu UI    Hide Menu UI


### メモリ管理とライフサイクル
- **Game Instance**の寿命はアプリケーション全体の寿命に一致するため、メニューの状態管理に適しています。
- サブシステムのメモリは自動的に管理され、ゲーム終了時に適切にクリーンアップされます。

以上の手順で、サブシステムを使用してメニュー状態を管理し、どのレベルからでもアクセスできるようになります。こうすることで、メニューの状態がゲームのさまざまなコンポーネントと連携しながら一貫して管理されるようになります。

### 具体的な手順を実装に含める:

#### 1. サブシステムにメニューの状態管理機能を追加
1. **MenuSubsystem**をダブルクリックして開きます。
2. 以下のように関数や変数を追加します:

  - **変数:**
    - **bIsMenuOpen** (Boolean): メニューが開いているかどうかを示します。

  - **関数:**
    - **SetMenuOpen(bool bOpen)**: メニューの開閉状態を設定する関数。
    - **IsMenuOpen()**: メニューが開いているかどうかを返す関数。

cpp
// MenuSubsystem.h
UCLASS()
class YOURGAME_API UMenuSubsystem : public UGameInstanceSubsystem
{
   GENERATED_BODY()

public:
   void SetMenuOpen(bool bOpen);
   bool IsMenuOpen() const;

private:
   bool bIsMenuOpen;
};

// MenuSubsystem.cpp
#include "MenuSubsystem.h"

void UMenuSubsystem::SetMenuOpen(bool bOpen)
{
   bIsMenuOpen = bOpen;
}

bool UMenuSubsystem::IsMenuOpen() const
{
   return bIsMenuOpen;
}


#### 2. ゲームインスタンスの設定
1. UE5エディターで「Project Settings」に移動し、「Maps & Modes」を選択します。
2. 「Default Game Instance」を自分のカスタムゲームインスタンスに設定します(必要に応じて新しいゲームインスタンスを作成)。

#### 3. プレイヤーキャラクターの設定
1. プレイヤーキャラクターのブループリントを開き、メニュー表示のトグル処理を設定します。

BP
Event IA_ToggleMenu
   ↓
Get Game Instance
   ↓
Cast to YourGameInstance
   ↓
Get Subsystem (MenuSubsystem)
   ↓
IsMenuOpen
   ↓
Branch (IsMenuOpen?)
   ↙          ↘
True      False
↓              ↓
SetMenuOpen(False)    SetMenuOpen(True)
Remove Mapping Context (MenuInputMapping)    Add Mapping Context (MenuInputMapping)
Add Mapping Context (PlayerInputMapping)    Remove Mapping Context (PlayerInputMapping)
Set Show Mouse Cursor (False)    Set Show Mouse Cursor (True)


#### 4. メニューウィジェットの設定
1. メニューウィジェットのブループリントを開き、Constructイベントで初期設定を行います。

BP
Event Construct
   ↓
Get Game Instance
   ↓
Cast to YourGameInstance
   ↓
Get Subsystem (MenuSubsystem)
   ↓
IsMenuOpen
   ↓
Branch (IsMenuOpen?)
   ↙          ↘
True      False
↓              ↓
Show Menu UI    Hide Menu UI


### まとめ
これらの手順を通じて、サブシステムを利用することでメニューの状態を管理し、いつでもどのレベルからでもその状態にアクセスできるようになります。これにより、ゲーム全体で一貫したメニュー状態管理が可能となります。

必要に応じて、サブシステムに追加の関数や変数を追加して、さらに複雑な状態管理を実現することもできます。

-------------------------------------------------------------------------------

sub systemクラスとgame instance subsystemの使い方の違いを教えてください


Unreal Engineには複数のサブシステム(Subsystem)クラスが存在し、それぞれが特定のライフサイクルや機能を持っています。特に`Subsystem`と`Game Instance Subsystem`の使用方法と目的について説明します。

### 1. Subsystem クラス
Subsystemは、特定のゲームシステムや機能を実装するための基本的なクラスです。以下の異なる種類のSubsystemがあります:
- **Engine Subsystem (UEngineSubsystem):** エンジン全体のライフタイムにわたって存在するサブシステムです。エンジンが初期化されるときに作成され、エンジンが終了するときに破棄されます。
- **Game Instance Subsystem (UGameInstanceSubsystem):** ゲームインスタンスのライフタイムにわたって存在するサブシステムです。ゲームが開始されるときに初期化され、終了する際に破棄されます。
- **Local Player Subsystem (ULocalPlayerSubsystem):** ローカルプレイヤーのライフタイムにわたって存在するサブシステムです。各ローカルプレイヤーに対応しています。
- **World Subsystem (UWorldSubsystem):** ワールド(レベル)ごとに存在するサブシステムです。各ワールドのライフタイムに対応します。

### 2. Game Instance Subsystem クラス
UGameInstanceSubsystemは、ゲーム全体を通して一貫した状態や機能を管理するために最もよく使われるサブシステムです。このサブシステムは、ゲームインスタンスのライフタイムに対応し、ゲームが起動している間ずっと存在します。

#### 特徴と使い方
- **永続性:** ゲーム全体を通じて一貫したデータ保持や管理が必要な場合に使用します(例:プレイヤーの設定、グローバルなゲームデータ、シングルトンパターン)。
- **アクセス方法:** UGameInstanceSubsystemは、ゲームインスタンスを介してアクセスされます。

cpp
// C++
class UMyGameInstanceSubsystem : public UGameInstanceSubsystem
{
   GENERATED_BODY()
public:
   // サブシステムの初期化
   virtual void Initialize(FSubsystemCollectionBase& Collection) override;
   // サブシステムのクリーンアップ
   virtual void Deinitialize() override;

   // メニューの状態を保持する例
   void SetMenuOpen(bool bOpen);
   bool IsMenuOpen() const;

private:
   bool bIsMenuOpen;
};
### 実際のアクセス方法
cpp
// C++
UMyGameInstanceSubsystem* Subsystem = GetGameInstance()->GetSubsystem<UMyGameInstanceSubsystem>();
BP
// ブループリント
Get Game Instance
   ↓
Get Subsystem (MyGameInstanceSubsystem)


### 3. 他のタイプのサブシステム
#### Engine Subsystem (UEngineSubsystem)
エンジン全体で共有される情報を管理するために使用されます。ゲームエンジンのライフタイムに対応します。たとえば、グローバル設定やエンジン全体にわたるサービスを管理するために使用されます。

cpp
// C++
class UMyEngineSubsystem : public UEngineSubsystem
{
   GENERATED_BODY()
};
#### World Subsystem (UWorldSubsystem)
各ワールドごとに固有のデータを管理するために使用されます。たとえば、特定のレベルの状態やイベントを管理します。

cpp
// C++
class UMyWorldSubsystem : public UWorldSubsystem
{
   GENERATED_BODY()
};

この記事が気に入ったらサポートをしてみませんか?