

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Unreal 用プラグイン: ゲームコードを統合
<a name="unreal-plugin-integrate"></a>

ゲームサーバーをフリートにデプロイする前に、ゲームコードに一連の更新を行い、Amazon GameLift Servers サービスで使用するゲームコンポーネントをパッケージ化する必要があります。

このトピックでは、最小限の統合を実行する手順について説明します。サーバー統合の場合は、提供されているコードサンプルを使用してプロジェクトのゲームモードを更新してください。
+ [ビルドターゲットとモジュールルールを設定する](#unreal-plugin-anywhere-integrate-setup)
+ [ゲームサーバーコードを更新する](#unreal-plugin-anywhere-integrate-simple-server)
+ [クライアントゲームマップを統合する](#unreal-plugin-anywhere-integrate-simple-client)
+ [ゲームコンポーネントをパッケージ化する](#unreal-plugin-anywhere-integrate-build)

## ビルドターゲットとモジュールルールを設定する
<a name="unreal-plugin-anywhere-integrate-setup"></a>

ゲームプロジェクトファイルを変更して、Amazon GameLift Servers で使用するビルドコンポーネントを適切に生成します。

**クライアントとサーバーのビルドターゲットを追加するには:**

1. ゲームプロジェクトのコードファイルを開き、ファイル `.../Games/{{[your application name]}}Source/{{[your application name]}}Target.cs` ファイルを見つけます。例: `.../Source/GameLiftUnrealAppTarget.cs`。(Visual Studio を使用する場合は、プロジェクトの `.sln` ファイルを開きます。)

1. このファイルをコピーして、`Source/` ディレクトリに 2 つの新しいターゲットファイルを作成します。
   + クライアントターゲット - 新しいファイルの名前を `{{[your application name]}}Client.Target.cs` に変更します。次のサンプルコードに示すように、コンテンツを編集してクラス名とターゲットタイプの値を更新します。

     ```
     using UnrealBuildTool;
       using System.Collections.Generic;
     
       public class GameLiftUnrealAppClientTarget :  TargetRules
      {
          public GameLiftUnrealAppClientTarget ( TargetInfo Target ) :  base ( Target )
          {
              Type = TargetType.Client;
              DefaultBuildSettings = BuildSettingsVersion.V2;
              IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1;
              ExtraModuleNames.Add( "GameLiftUnrealApp");
          }
      }
     ```
   + サーバーターゲット - 新しいファイルの名前を `{{[your application name]}}Server.Target.cs` に変更します。次のサンプルコードに示すように、コンテンツを編集してクラス名とターゲットタイプの値を更新します。

     ```
     using UnrealBuildTool;
       using System.Collections.Generic;
     
       public class GameLiftUnrealAppServerTarget :  TargetRules
      {
          public GameLiftUnrealAppServerTarget ( TargetInfo Target ) :  base ( Target )
          {
              Type = TargetType.Server;
              DefaultBuildSettings = BuildSettingsVersion.V2;
              IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1;
              ExtraModuleNames.Add( "GameLiftUnrealApp");
          }
      }
     ```

1. プロジェクトファイルを再生成します。Visual Studio を使用している場合は、ゲームプロジェクトの `.uproject` ファイルを右クリックし、**[Visual Studio プロジェクトファイルの生成]** を選択します。

**ゲームプロジェクトモジュールルールを更新するには:**

ゲームプロジェクトのモジュールルールを更新して、プラグインに依存します。

1. ゲームプロジェクトのコードファイルを開き、ファイル `.../Games/{{[your application name]}}Source/{{[your application name]}}.Build.cs` ファイルを見つけます。例えば、`.../Source/GameLiftUnrealApp.Build.cs` などです。(Visual Studio を使用する場合は、プロジェクトの `.sln` ファイルを開きます。)

1. 次のサンプルコードに示すように、`ModuleRules` クラスを見つけて更新します。

   ```
   using UnrealBuildTool;
   
     public class GameLiftUnrealApp :  ModuleRules
    {
        public GameLiftUnrealApp ( ReadOnlyTargetRules Target ) :  base ( Target )
        {
            PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
            PublicDependencyModuleNames.AddRange( new string[] {  "Core",  "CoreUObject",  "Engine",  "InputCore",  "HeadMountedDisplay",  "EnhancedInput" });
        // Add the following section
   	   if (Target.Type == TargetType.Server)
   	   {
                  PublicDependencyModuleNames.Add("GameLiftServerSDK");
             }
             else
             {
                  PublicDefinitions.Add("WITH_GAMELIFT=0");
             }
            bEnableExceptions =  true;
        }
    }
   ```

1. 新しいターゲットファイルを作成し、モジュールルールを変更したら、ゲームプロジェクトを再構築します。

## ゲームサーバーコードを更新する
<a name="unreal-plugin-anywhere-integrate-simple-server"></a>

ゲームサーバーコードを更新して、ゲームサーバープロセスと Amazon GameLift Servers サービス間の通信を有効にします。ゲームサーバーは、新しいゲームセッションを開始および停止するなど、Amazon GameLift Servers からのリクエストに応答できる必要があります。

**Amazon GameLift Servers のサーバーコードを追加するには**

1. Code Editor で、ゲームプロジェクトのソリューション (`.sln`) ファイルを開きます。通常はプロジェクトのルートフォルダにあります。例: `GameLiftUnrealApp.sln`。

1. ソリューションを開いた状態で、プロジェクトのゲームモードヘッダーファイル: `[project-name]GameMode.h` ファイルを探します。例: `GameLiftUnrealAppGameMode.h`。

1. ヘッダーファイルを次のサンプルコードに合わせて変更します。必ず「GameLiftServer」を独自のプロジェクト名に置き換えてください。これらの更新はゲームサーバー固有のものです。クライアントで使用するために、元のゲームモードファイルのバックアップコピーを作成することをお勧めします。

### gameMode.h コードの例
<a name="w2aab9c11b9c19c27c11b7b1"></a>

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "GameLiftUnrealAppGameMode.generated.h"

struct FProcessParameters;

DECLARE_LOG_CATEGORY_EXTERN(GameServerLog, Log, All);

UCLASS(minimalapi)
class AGameLiftUnrealAppGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:
    AGameLiftUnrealAppGameMode();

protected:
    virtual void BeginPlay() override;

private:
    void InitGameLift();

private:
    TSharedPtr<FProcessParameters> ProcessParameters;
};
```
+ 関連するソースファイルの `[project-name]GameMode.cpp` ファイル (`GameLiftUnrealAppGameMode.cpp` など) を開きます。コードを次のサンプルコードに合わせて変更します。必ず「GameLiftUnrealApp」を独自のプロジェクト名に置き換えてください。これらの更新はゲームサーバー固有のものです。クライアントで使用するために、元のファイルのバックアップコピーを作成することをお勧めします。

  以下のコード例は、Amazon GameLift Servers とのサーバー統合に最低限必要な要素を追加する方法を示しています。
  + Amazon GameLift Servers API クライアントを初期化します。Amazon GameLift Servers Anywhere フリートには、サーバーパラメータを指定した `InitSDK()` コールが必要です。Anywhere フリートに接続すると、プラグインはサーバーパラメータをコンソール引数として保存します。サンプルコードはランタイム時に値にアクセスできます。
  + `OnStartGameSession`、`OnProcessTerminate`、`onHealthCheck` など、Amazon GameLift Servers サービスからのリクエストに応答する必須のコールバック関数を実装します。
  + 指定されたポートで `ProcessReady()` を呼び出して、ゲームセッションをホストする準備ができたときに Amazon GameLift Servers サービスに通知します。

### ゲームサーバーコードの例
<a name="w2aab9c11b9c19c27c11c11b1"></a>

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

#include "GameLiftUnrealAppGameMode.h"

#include "UObject/ConstructorHelpers.h"
#include "Kismet/GameplayStatics.h"

#if WITH_GAMELIFT
#include "GameLiftServerSDK.h"
#include "GameLiftServerSDKModels.h"
#endif

#include "GenericPlatform/GenericPlatformOutputDevices.h"

DEFINE_LOG_CATEGORY(GameServerLog);

AGameLiftUnrealAppGameMode::AGameLiftUnrealAppGameMode() :
    ProcessParameters(nullptr)
{
    // Set default pawn class to our Blueprinted character
    static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter"));

    if (PlayerPawnBPClass.Class != NULL)
    {
        DefaultPawnClass = PlayerPawnBPClass.Class;
    }

    UE_LOG(GameServerLog, Log, TEXT("Initializing AGameLiftUnrealAppGameMode..."));
}

void AGameLiftUnrealAppGameMode::BeginPlay()
{
    Super::BeginPlay();

#if WITH_GAMELIFT
    InitGameLift();
#endif
}

void AGameLiftUnrealAppGameMode::InitGameLift()
{
#if WITH_GAMELIFT
    UE_LOG(GameServerLog, Log, TEXT("Calling InitGameLift..."));

    // Getting the module first.
    FGameLiftServerSDKModule* GameLiftSdkModule = &FModuleManager::LoadModuleChecked<FGameLiftServerSDKModule>(FName("GameLiftServerSDK"));

    //Define the server parameters for a GameLift Anywhere fleet. These are not needed for a GameLift managed EC2 fleet.
    FServerParameters ServerParametersForAnywhere;

    bool bIsAnywhereActive = false;
    if (FParse::Param(FCommandLine::Get(), TEXT("glAnywhere")))
    {
        bIsAnywhereActive = true;
    }

    if (bIsAnywhereActive)
    {
        UE_LOG(GameServerLog, Log, TEXT("Configuring server parameters for Anywhere..."));

        // If GameLift Anywhere is enabled, parse command line arguments and pass them in the ServerParameters object.
        FString glAnywhereWebSocketUrl = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereWebSocketUrl="), glAnywhereWebSocketUrl))
        {
            ServerParametersForAnywhere.m_webSocketUrl = TCHAR_TO_UTF8(*glAnywhereWebSocketUrl);
        }

        FString glAnywhereFleetId = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereFleetId="), glAnywhereFleetId))
        {
            ServerParametersForAnywhere.m_fleetId = TCHAR_TO_UTF8(*glAnywhereFleetId);
        }

        FString glAnywhereProcessId = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereProcessId="), glAnywhereProcessId))
        {
            ServerParametersForAnywhere.m_processId = TCHAR_TO_UTF8(*glAnywhereProcessId);
        }
        else
        {
            // If no ProcessId is passed as a command line argument, generate a randomized unique string.
            FString TimeString = FString::FromInt(std::time(nullptr));
            FString ProcessId = "ProcessId_" + TimeString;
            ServerParametersForAnywhere.m_processId = TCHAR_TO_UTF8(*ProcessId);
        }

        FString glAnywhereHostId = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereHostId="), glAnywhereHostId))
        {
            ServerParametersForAnywhere.m_hostId = TCHAR_TO_UTF8(*glAnywhereHostId);
        }

        FString glAnywhereAuthToken = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereAuthToken="), glAnywhereAuthToken))
        {
            ServerParametersForAnywhere.m_authToken = TCHAR_TO_UTF8(*glAnywhereAuthToken);
        }

        FString glAnywhereAwsRegion = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereAwsRegion="), glAnywhereAwsRegion))
        {
            ServerParametersForAnywhere.m_awsRegion = TCHAR_TO_UTF8(*glAnywhereAwsRegion);
        }

        FString glAnywhereAccessKey = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereAccessKey="), glAnywhereAccessKey))
        {
            ServerParametersForAnywhere.m_accessKey = TCHAR_TO_UTF8(*glAnywhereAccessKey);
        }

        FString glAnywhereSecretKey = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereSecretKey="), glAnywhereSecretKey))
        {
            ServerParametersForAnywhere.m_secretKey = TCHAR_TO_UTF8(*glAnywhereSecretKey);
        }

        FString glAnywhereSessionToken = "";
        if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereSessionToken="), glAnywhereSessionToken))
        {
            ServerParametersForAnywhere.m_sessionToken = TCHAR_TO_UTF8(*glAnywhereSessionToken);
        }

        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_YELLOW);
        UE_LOG(GameServerLog, Log, TEXT(">>>> WebSocket URL: %s"), *ServerParametersForAnywhere.m_webSocketUrl);
        UE_LOG(GameServerLog, Log, TEXT(">>>> Fleet ID: %s"), *ServerParametersForAnywhere.m_fleetId);
        UE_LOG(GameServerLog, Log, TEXT(">>>> Process ID: %s"), *ServerParametersForAnywhere.m_processId);
        UE_LOG(GameServerLog, Log, TEXT(">>>> Host ID (Compute Name): %s"), *ServerParametersForAnywhere.m_hostId);
        UE_LOG(GameServerLog, Log, TEXT(">>>> Auth Token: %s"), *ServerParametersForAnywhere.m_authToken);
        UE_LOG(GameServerLog, Log, TEXT(">>>> Aws Region: %s"), *ServerParametersForAnywhere.m_awsRegion);
        UE_LOG(GameServerLog, Log, TEXT(">>>> Access Key: %s"), *ServerParametersForAnywhere.m_accessKey);
        UE_LOG(GameServerLog, Log, TEXT(">>>> Secret Key: %s"), *ServerParametersForAnywhere.m_secretKey);
        UE_LOG(GameServerLog, Log, TEXT(">>>> Session Token: %s"), *ServerParametersForAnywhere.m_sessionToken);
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE);
    }

    UE_LOG(GameServerLog, Log, TEXT("Initializing the GameLift Server..."));

    //InitSDK will establish a local connection with GameLift's agent to enable further communication.
    FGameLiftGenericOutcome InitSdkOutcome = GameLiftSdkModule->InitSDK(ServerParametersForAnywhere);
    if (InitSdkOutcome.IsSuccess())
    {
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_GREEN);
        UE_LOG(GameServerLog, Log, TEXT("GameLift InitSDK succeeded!"));
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE);
    }
    else
    {
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_RED);
        UE_LOG(GameServerLog, Log, TEXT("ERROR: InitSDK failed : ("));
        FGameLiftError GameLiftError = InitSdkOutcome.GetError();
        UE_LOG(GameServerLog, Log, TEXT("ERROR: %s"), *GameLiftError.m_errorMessage);
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE);
        return;
    }

    ProcessParameters = MakeShared<FProcessParameters>();

    //When a game session is created, Amazon GameLift Servers sends an activation request to the game server and passes along the game session object containing game properties and other settings.
    //Here is where a game server should take action based on the game session object.
    //Once the game server is ready to receive incoming player connections, it should invoke GameLiftServerAPI.ActivateGameSession()
    ProcessParameters->OnStartGameSession.BindLambda([=](Aws::GameLift::Server::Model::GameSession InGameSession)
        {
            FString GameSessionId = FString(InGameSession.GetGameSessionId());
            UE_LOG(GameServerLog, Log, TEXT("GameSession Initializing: %s"), *GameSessionId);
            GameLiftSdkModule->ActivateGameSession();
        });

    //OnProcessTerminate callback. Amazon GameLift Servers will invoke this callback before shutting down an instance hosting this game server.
    //It gives this game server a chance to save its state, communicate with services, etc., before being shut down.
    //In this case, we simply tell Amazon GameLift Servers we are indeed going to shutdown.
    ProcessParameters->OnTerminate.BindLambda([=]()
        {
            UE_LOG(GameServerLog, Log, TEXT("Game Server Process is terminating"));
            // First call ProcessEnding()
            FGameLiftGenericOutcome processEndingOutcome = GameLiftSdkModule->ProcessEnding();
            // Then call Destroy() to free the SDK from memory
            FGameLiftGenericOutcome destroyOutcome = GameLiftSdkModule->Destroy();
            // Exit the process with success or failure
            if (processEndingOutcome.IsSuccess() && destroyOutcome.IsSuccess()) {
                UE_LOG(GameServerLog, Log, TEXT("Server process ending successfully"));
            }
            else {
                if (!processEndingOutcome.IsSuccess()) {
                    const FGameLiftError& error = processEndingOutcome.GetError();
                    UE_LOG(GameServerLog, Error, TEXT("ProcessEnding() failed. Error: %s"),
                    error.m_errorMessage.IsEmpty() ? TEXT("Unknown error") : *error.m_errorMessage);
                }
                if (!destroyOutcome.IsSuccess()) {
                    const FGameLiftError& error = destroyOutcome.GetError();
                    UE_LOG(GameServerLog, Error, TEXT("Destroy() failed. Error: %s"),
                    error.m_errorMessage.IsEmpty() ? TEXT("Unknown error") : *error.m_errorMessage);
                }
            }
        });

    //This is the HealthCheck callback.
    //Amazon GameLift Servers will invoke this callback every 60 seconds or so.
    //Here, a game server might want to check the health of dependencies and such.
    //Simply return true if healthy, false otherwise.
    //The game server has 60 seconds to respond with its health status. Amazon GameLift Servers will default to 'false' if the game server doesn't respond in time.
    //In this case, we're always healthy!
    ProcessParameters->OnHealthCheck.BindLambda([]()
        {
            UE_LOG(GameServerLog, Log, TEXT("Performing Health Check"));
            return true;
        });

    //GameServer.exe -port=7777 LOG=server.mylog
    ProcessParameters->port = FURL::UrlConfig.DefaultPort;
    TArray<FString> CommandLineTokens;
    TArray<FString> CommandLineSwitches;

    FCommandLine::Parse(FCommandLine::Get(), CommandLineTokens, CommandLineSwitches);

    for (FString SwitchStr : CommandLineSwitches)
    {
        FString Key;
        FString Value;

        if (SwitchStr.Split("=", &Key, &Value))
        {
            if (Key.Equals("port"))
            {
                ProcessParameters->port = FCString::Atoi(*Value);
            }
        }
    }

    //Here, the game server tells Amazon GameLift Servers where to find game session log files.
    //At the end of a game session, Amazon GameLift Servers uploads everything in the specified 
    //location and stores it in the cloud for access later.
    TArray<FString> Logfiles;
    Logfiles.Add(TEXT("GameLiftUnrealApp/Saved/Logs/server.log"));
    ProcessParameters->logParameters = Logfiles;

    //The game server calls ProcessReady() to tell Amazon GameLift Servers it's ready to host game sessions.
    UE_LOG(GameServerLog, Log, TEXT("Calling Process Ready..."));
    FGameLiftGenericOutcome ProcessReadyOutcome = GameLiftSdkModule->ProcessReady(*ProcessParameters);

    if (ProcessReadyOutcome.IsSuccess())
    {
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_GREEN);
        UE_LOG(GameServerLog, Log, TEXT("Process Ready!"));
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE);
    }
    else
    {
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_RED);
        UE_LOG(GameServerLog, Log, TEXT("ERROR: Process Ready Failed!"));
        FGameLiftError ProcessReadyError = ProcessReadyOutcome.GetError();
        UE_LOG(GameServerLog, Log, TEXT("ERROR: %s"), *ProcessReadyError.m_errorMessage);
        UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE);
    }

    UE_LOG(GameServerLog, Log, TEXT("InitGameLift completed!"));
#endif
}
```

## クライアントゲームマップを統合する
<a name="unreal-plugin-anywhere-integrate-simple-client"></a>

スタートアップゲームマップには、ゲームセッションをリクエストしたり、接続情報を使用してゲームセッションに接続するための基本コードが既に含まれているブループリントロジックと UI 要素が含まれています。このマップはそのまま使用することも、必要に応じて変更することもできます。スタートアップ時のゲームマップは、Unreal Engine が提供する Third Person テンプレートプロジェクトなどの他のゲームアセットと一緒に使用してください。これらのアセットはコンテンツブラウザで使用できます。プラグインのデプロイワークフローをテストしたり、ゲーム用のカスタムバックエンドサービスを作成したりするためのガイドとして使用できます。

このスタートアップマップには以下の特徴があります。
+ Anywhere フリートとマネージド EC2 フリートの両方のロジックが含まれています。クライアントを実行するときに、どちらかのフリートに接続することを選択できます。
+ クライアントの機能には、ゲームセッションの検索 (`SearchGameSessions()`)、新しいゲームセッションの作成 (`CreateGameSession()`)、ゲームセッションへの直接参加が含まれます。
+ プロジェクトの Amazon Cognito ユーザープールから一意のプレイヤー ID を取得します (これはデプロイされた Anywhere ソリューションの一部です)。

**スタートアップゲームマップを使用するには**

1. UE エディタで、**[プロジェクト設定、マップ & モード]** ページを開き、**[デフォルトマップ]** セクションを展開します。

1. **[エディタのスタートアップマップ]** では、ドロップダウンリストで [StartupMap] を選択します。`... > Unreal Projects/[project-name]/Plugins/Amazon GameLift Servers Plugin Content/Maps` にあるファイルを検索しなければいけない場合があります。

1. **[ゲームのデフォルトマップ]** では、ドロップダウンリストで [StartupMap] を選択します。

1. **サーバーデフォルトマップ**では、Unreal Engine 5.6 以降では「Lv1\_ThirdPerson」、以前のバージョンではThirdPersonMap」を選択します。これはゲームプロジェクトに含まれるデフォルトのマップです。このマップはゲーム内の 2 人のプレイヤー向けに設計されています。

1. サーバーのデフォルトマップの詳細パネルを開きます。**[GameMode のオーバーライド]** を「なし」に設定します。

1. **[デフォルトモード]** セクションを展開し、**[グローバルデフォルトサーバーゲームモード]** をサーバー統合用に更新したゲームモードに設定します。

プロジェクトにこれらの変更を加えたら、ゲームコンポーネントをビルドできるようになります。

**注記**  
Unreal Engine 5.6 以降では、ゲームサーバーに接続した後にキャラクターを移動できない場合は、BP\_ThirdPersonCharacter ブループリントを更新して、次`IMC_MouseLook`に示すように `IMC_Default`と の入力マッピングコンテキストを追加します。  

![](http://docs.aws.amazon.com/ja_jp/gameliftservers/latest/developerguide/images/unreal-enhanced-input-blueprint.png)


## ゲームコンポーネントをパッケージ化する
<a name="unreal-plugin-anywhere-integrate-build"></a>

**ゲームサーバーとゲームクライアントビルドをパッケージ化する**

1. Unreal Engine エディタのソースビルドバージョンでゲームプロジェクトを開きます。

1. Unreal Engine 5.6 以降を使用している場合は、**編集、プロジェクト設定、パッケージング**を参照してください。**プロジェクトコンテンツディレクトリですべてクック**を見つけて有効にします。

1. ゲームサーバーとゲームクライアントビルドをパッケージ化します。

   1. ターゲットを選択します。**[プラットフォーム、Windows]** に移動し、次のいずれかを選択します。
      + サーバー: `[your-application-name]Server`
      + クライアント: `[your-application-name]Client`

   1. ビルドを開始します。**[プラットフォーム、Windows、パッケージプロジェクト]** に移動します。

パッケージ化処理を行うたびに、`[your-application-name]Client.exe` または `[your-application-name]Server.exe` という実行ファイルが生成されます。

プラグインで、ローカルワークステーションにクライアントとサーバーのビルド実行ファイルへのパスを設定します。