# Diarkis サーバーへの接続と切断

ここでは簡単なチュートリアルを通じて Diarkis Unreal Engine Plugin (以降、UE Plugin) のインストール手順や Unreal Engine から Diarkis Module の初期化と終了方法や Diarkis サーバーへの接続方法などの基本的な使い方について解説します。

{% hint style="info" %}
このチュートリアルは UE 5.6.1 を使用しています。異なるバージョンをお使いの場合、UI や挙動が異なる可能性があるため、同じバージョンの使用をお勧めします。
{% endhint %}

#### プロジェクトの作成

Blank テンプレートから新規プロジェクトを作成します。

このチュートリアルでは C++ を選択します。

<figure><img src="/files/hV4y2qZ4iYAG2gZIJp6j" alt=""><figcaption></figcaption></figure>

#### UE Plugin のインストール手順

1. **DiarkisPluginSample の解凍**
   * DiarkisPluginSample を解凍します。
2. **Plugins フォルダに Diarkis フォルダを移動**&#x20;
   * 解凍した DiarkisPluginSample の Plugins フォルダ内の Diarkis フォルダをチュートリアルプロジェクトの Plugins フォルダにコピーします。<br>

     ```
     .
     ├── Config
     ├── Content
     ├── Source
     ├── Plugins ← (無ければフォルダを作成)
     │   └── Diarkis ← (ここにプラグインを配置)
     │       ├── Config
     │       ├── Content
     │       ├── Source
     │       └── Diarkis.uplugin
     └── Tutorial.uproject
     ```
3. **UE Plugin をプロジェクトの依存関係に追加**
   * `Source/Tutorial/Tutorial.Build.cs` を開き、 以下のようにプラグインを依存関係に追加します。<br>

     ```csharp
     // Tutorial.Build.cs

     public class Tutorial : ModuleRules
     {
     	public Tutorial(ReadOnlyTargetRules Target) : base(Target)
     	{
     		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
     	
     		PublicDependencyModuleNames.AddRange(new string[] {
     			"Core",
     			"CoreUObject",
     			"Engine",
     			"InputCore",
     			"EnhancedInput",
     			"Diarkis" // <-- 追加
     		});
     ```
4. **プロジェクトを再ビルド**
   * UE Plugin を追加した後、プロジェクトを再ビルドします。

#### **GameInstanceSubsystem の子クラスの作成**

Diarkis サーバへの接続、切断を行うために GameInstanceSubsystem の子クラスを作成します。

Tools -> New C++ Class をクリックし、親クラスに GameInstanceSubsystem を指定します。

<figure><img src="/files/tBrwnsTRrP2UsPNQ5IB1" alt=""><figcaption></figcaption></figure>

TutorialSubsystem という名前でクラスを作成します。

<figure><img src="/files/ZCvSSqbJYFZ1lUCQunwm" alt=""><figcaption></figcaption></figure>

このチュートリアルではここで作成した TutorialSubsystem クラスを使用して、UE Plugin の基本的な使い方を解説します。

#### Diarkis Module の初期化と終了

はじめに **Diarkis ランタイム・ライブラリ** および **Diarkis Module** を初期化するために `DiarkisInterfaceBase::DiarkisInit()` を呼び出します。 この処理はアプリケーション全体で最初に一度だけ実行する必要があります。\
また、アプリケーションの終了時に `DiarkisInterfaceBase::DiarkisDestroy()` を呼び出して Diarkis 全体の終了処理を行います。この処理は `DiarkisInterfaceBase::DiarkisInit()` と対になっていて、`DiarkisInit` 同様にアプリケーションのライフサイクル全体で一度だけ呼び出してください。

このチュートリアルでは GameInstanceSubsystem の子クラスを使い、`Initialize` 関数の中で `DiarkisInterfaceBase::DiarkisInit()` を呼び出し、`Deinitialize` 関数の中で `DiarkisInterfaceBase::DiarkisDestroy()` を呼び出します。

```cpp
// TutorialSubsystem.h

#pragma once

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

UCLASS()
class UTutorialSubsystem : public UGameInstanceSubsystem
{
    GENERATED_BODY()

public:
    UTutorialSubsystem();

    virtual void Initialize(FSubsystemCollectionBase& Collection) override;
    virtual void Deinitialize() override;
};
```

```cpp
// TutorialSubsystem.cpp


#include "TutorialSubsystem.h"
#include "DiarkisInterfaceBase.h"

UTutorialSubsystem::UTutorialSubsystem()
{
    UE_LOG(LogTemp, Log, TEXT("UTutorialSubsystem: Constructor"));
}

void UTutorialSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
    Super::Initialize(Collection);

    UE_LOG(LogTemp, Log, TEXT("UTutorialSubsystem: Initialize - Calling DiarkisInit"));
    Diarkis::DiarkisInterfaceBase::DiarkisInit("logs", Diarkis::LogOutType::FILE_OUT, true);
}

void UTutorialSubsystem::Deinitialize()
{
    UE_LOG(LogTemp, Log, TEXT("UTutorialSubsystem: Deinitialize - Calling DiarkisDestroy"));
    Diarkis::DiarkisInterfaceBase::DiarkisDestroy();

    Super::Deinitialize();
}

```

ここでは 1 クライアントからの利用を前提とした簡単なチュートリアルのため、DiarkisInit 関数の logDirName 引数で "logs" を指定していますが、実際には uid を指定するなど複数クライアントでもログが上書きされないように設定してください。

```cpp
Diarkis::DiarkisInterfaceBase::DiarkisInit("logs", Diarkis::LogOutType::FILE_OUT, true);
```

LogTemp カテゴリーのみ表示するようにフィルタを設定します。

<figure><img src="/files/GoK7CMQFVTB46kE1Msr9" alt=""><figcaption></figcaption></figure>

ゲームを実行し、ゲーム起動時に `LogTemp: UTutorialSubsystem: Initialize - Calling DiarkisInit` が表示され、ゲーム終了時に `LogTemp: UTutorialSubsystem: Deinitialize - Calling DiarkisDestroy` が表示されることを確認します。

#### Diarkis サーバーへの接続と切断

TutorialSubsystem クラスに処理を追加し、ゲーム起動時に Diarkis サーバーへの接続、ゲーム終了時に切断を行います。

最終的なコードは下記になります。

```cpp
// TutorialSubsystem.h

#pragma once

#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "DiarkisInterfaceBase.h"
#include "TutorialSubsystem.generated.h"

UCLASS()
class TUTORIAL_API UTutorialSubsystem : public UGameInstanceSubsystem
{
	GENERATED_BODY()
	
public:
	UTutorialSubsystem();

	void Initialize(FSubsystemCollectionBase& Collection) override;
	void Deinitialize() override;

private:
	std::shared_ptr<Diarkis::DiarkisInterfaceBase> DiarkisInterfaceInstance;
};

```

```cpp
// TutorialSubsystem.cpp


#include "TutorialSubsystem.h"
#include "Kismet/KismetSystemLibrary.h"

UTutorialSubsystem::UTutorialSubsystem()
{
	UE_LOG(LogTemp, Log, TEXT("UTutorialSubsystem: Constructor"));
}

void UTutorialSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);

	// Diarkis ライブラリの初期化
	// Initialize Diarkis library
	UE_LOG(LogTemp, Log, TEXT("UTutorialSubsystem: Initialize - Calling DiarkisInit"));
	Diarkis::DiarkisInterfaceBase::DiarkisInit("logs", Diarkis::LogOutType::FILE_OUT, true);

	// DiarkisInterfaceインスタンスの作成
	// Create DiarkisInterface instance
	DiarkisInterfaceInstance = Diarkis::DiarkisAllocShared<Diarkis::DiarkisInterfaceBase>("AAAA");
	if (!DiarkisInterfaceInstance)
	{
		UE_LOG(LogTemp, Error, TEXT("DiarkisInterfaceInstance creation failed"));
		Diarkis::DiarkisInterfaceBase::DiarkisDestroy();

		UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
	}

	// Diarkis UDP クラスを初期化
	// Initialize Diarkis UDP class
	DiarkisInterfaceInstance->SetupUdp();

	// Http サーバーから UDP サーバーの Endpoint を取得
	// Get the endpoint of the UDP server from the HTTP server
	char endpoint[256];
	if (!DiarkisInterfaceInstance->GetEndpoint("127.0.0.1:7000", "", "UDP", endpoint, 256))
	{
		UE_LOG(LogTemp, Error, TEXT("Failed to get UDP endpoint"));

		Diarkis::DiarkisInterfaceBase::DiarkisDestroy();
		UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
	}

	UE_LOG(LogTemp, Log, TEXT("Endpoint: %s"), UTF8_TO_TCHAR(endpoint));

	// UDP サーバーに接続
	// Connect to the UDP server
	UE_LOG(LogTemp, Log, TEXT("Connecting to the UDP server..."));
	bool result = DiarkisInterfaceInstance->ConnectUdp(endpoint);

	if (!result)
	{
		UE_LOG(LogTemp, Error, TEXT("Failed to connect to the UDP server"));
		Diarkis::DiarkisInterfaceBase::DiarkisDestroy();
		UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
	}

	UE_LOG(LogTemp, Log, TEXT("Connected to the UDP server"));
}

void UTutorialSubsystem::Deinitialize()
{
	if (!DiarkisInterfaceInstance)
	{
		UE_LOG(LogTemp, Warning, TEXT("DiarkisInterfaceInstance is null during Deinitialize"));

		DiarkisInterfaceBase::DiarkisDestroy();
		Super::Deinitialize();
		return;
	}

	// UDP サーバーから切断
	// Disconnect from the UDP server
	UE_LOG(LogTemp, Log, TEXT("Disconnecting from the UDP server..."));
	DiarkisInterfaceInstance->Disconnect();
	UE_LOG(LogTemp, Log, TEXT("Disconnected from the UDP server."));

	DiarkisInterfaceInstance.reset();

	UE_LOG(LogTemp, Log, TEXT("UTutorialSubsystem: Deinitialize - Calling DiarkisDestroy"));
	Diarkis::DiarkisInterfaceBase::DiarkisDestroy();

	Super::Deinitialize();
}

```

処理を追加した後は、再度ビルドし、ゲーム起動時に `"Connected to the UDP server"` というログが表示され、ゲーム終了時に `"Disconnected from the UDP server."` というログが表示されることを確認します。

このチュートリアルでは UID を固定の文字列  `"AAAA"` として指定していますが、実際にはユーザー情報に合わせて設定します。

```cpp
DiarkisInterfaceInstance = Diarkis::DiarkisAllocShared<Diarkis::DiarkisInterfaceBase>("AAAA");
```

このチュートリアルではエンドポイントに `"127.0.0.1:7000"` を指定し、クライアントキーに空文字  `""`  を指定していますが、ご利用の環境に合わせて変更してください。

```cpp
if (!DiarkisInterfaceInstance->GetEndpoint("127.0.0.1:7000", "", "UDP", endpoint, 256))
```

ここでは `ConnectUdp` 関数の戻り値で接続できたかどうかを判断していますが、エンドポイントに接続できない場合、タイムアウトされるまで処理が止まります。実際のゲームでは応答性のために `ConnectAsync` 関数と コールバック関数を使い、接続できたかどうかを判断することをお勧めします。詳細については次のページを参照してください。

```cpp
	bool result = DiarkisInterfaceInstance->ConnectUdp(endpoint);

	if (!result)
	{
		UE_LOG(LogTemp, Error, TEXT("Failed to connect to the UDP server"));
		Diarkis::DiarkisInterfaceBase::DiarkisDestroy();
		UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
	}

	UE_LOG(LogTemp, Log, TEXT("Connected to the UDP server"));
```

ここまでで UE Plugin を使い、Diarkis サーバーへの接続と切断が実行できました。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.diarkis.io/diarkis-client/chtoriaru/unreal-engine-chtoriaru/diarkis-sbhenoto.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
