Plugin para Unreal: configura las pruebas locales con Amazon GameLift Anywhere - Amazon GameLift

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Plugin para Unreal: configura las pruebas locales con Amazon GameLift Anywhere

En este flujo de trabajo, añades el código de juego de cliente y servidor para las GameLift funciones de Amazon y utilizas el complemento para designar tu estación de trabajo local como host de servidor de juegos de prueba. Cuando haya completado las tareas de integración, utilice el complemento para crear los componentes de cliente y servidor de juegos.

Para iniciar el flujo de trabajo de Amazon GameLift Anywhere:
  • En la barra de herramientas principal del editor Unreal, elige el GameLift menú Amazon y selecciona Host with Anywhere. Con esta acción se abre la página del complemento Implementar Anywhere, que presenta un proceso de seis pasos para integrar, crear y lanzar los componentes del juego.

Paso 1: Configura tu perfil.

Elija el perfil que desee utilizar al seguir este flujo de trabajo. El perfil que seleccione afectará a todos los pasos del flujo de trabajo. Todos los recursos que cree están asociados a la AWS cuenta del perfil y se colocan en la AWS región predeterminada del perfil. Los permisos del usuario del perfil determinan su acceso a AWS los recursos y las acciones.

Para configurar un perfil de usuario
  1. Seleccione un perfil de la lista desplegable de perfiles disponibles. Si aún no tienes un perfil o quieres crear uno nuevo, ve al GameLift menú de Amazon y selecciona Establecer perfiles AWS de usuario.

  2. Si el estado de bootstrap no es «Activo», selecciona el perfil de Bootstrap y espera a que el estado cambie a «Activo».

Paso 2: Configuración del código de juego

En este paso, se realizará una serie de actualizaciones en el código del cliente y servidor para añadir la funcionalidad de alojamiento. Si aún no has configurado una versión original del editor Unreal, el complemento proporciona enlaces a las instrucciones y al código fuente.

Con el complemento, podrá aprovechar algunas ventajas a la hora de integrar el código del juego. Puede realizar una integración mínima para configurar la funcionalidad básica de alojamiento. También podrá realizar una integración personalizada más amplia. La información de esta sección describe la opción de integración mínima. Usa los mapas de prueba incluidos con el complemento para añadir la GameLift funcionalidad del cliente Amazon a tu proyecto de juego. Para la integración del servidor, utilice el ejemplo de código proporcionado para actualizar el modo de juego de su proyecto.

Integración del modo de juego del servidor

Añade un código de servidor al juego que permita la comunicación entre el servidor del juego y el GameLift servicio de Amazon. Tu servidor de juegos debe poder responder a las solicitudes de Amazon GameLift, por ejemplo, para iniciar una nueva sesión de juego, y también informar sobre el estado del servidor de juegos y las conexiones de los jugadores.

Para añadir el código de servidor de Amazon GameLift
  1. En el editor de código, abra el archivo de la solución (.sln) del proyecto de juego, que normalmente se encuentra en la carpeta raíz del proyecto. Por ejemplo: GameLiftUnrealApp.sln.

  2. Con la solución abierta, busque el archivo de cabecera del modo de juego del proyecto: archivo [project-name]GameMode.h. Por ejemplo: GameLiftUnrealAppGameMode.h.

  3. Cambie el archivo de encabezado para alinearlo con el siguiente código de ejemplo. Asegúrese de sustituir "GameLiftServer" por el nombre de su propio proyecto. Estas actualizaciones son específicas del servidor de juegos; le recomendamos que realice una copia de seguridad de los archivos originales del modo de juego para utilizarla con el cliente.

    // 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 "GameLiftServerGameMode.generated.h" struct FProcessParameters; DECLARE_LOG_CATEGORY_EXTERN(GameServerLog, Log, All); UCLASS(minimalapi) class AGameLiftServerGameMode : public AGameModeBase { GENERATED_BODY() public: AGameLiftServerGameMode(); protected: virtual void BeginPlay() override; private: void InitGameLift(); private: TSharedPtr<FProcessParameters> ProcessParameters; };
  4. Abra el archivo [project-name]GameMode.cpp del archivo de origen relacionado (por ejemplo, GameLiftUnrealAppGameMode.cpp). Cambie el código para alinearlo con el siguiente código de ejemplo. Asegúrese de reemplazar «GameLiftUnrealApp» por el nombre de su propio proyecto. Estas actualizaciones son específicas del servidor de juegos; le recomendamos que realice una copia de seguridad del archivo original para utilizarla con el cliente.

    El siguiente código de ejemplo muestra cómo añadir los elementos mínimos necesarios para la integración del servidor con Amazon GameLift:

    • Inicializa un GameLift API cliente de Amazon. La InitSDK() llamada con los parámetros del servidor es obligatoria para una flota de Amazon GameLift Anywhere. Cuando se conecta a una flota de Anywhere, el complemento almacena los parámetros del servidor como argumentos de la consola. El código de ejemplo puede acceder a los valores en tiempo de ejecución.

    • Implemente las funciones de devolución de llamada necesarias para responder a las solicitudes del GameLift servicio de Amazon, incluidas OnStartGameSessionOnProcessTerminate, yonHealthCheck.

    • ProcessReady()Llama a un puerto designado para notificar al GameLift servicio de Amazon cuando estés listo para organizar sesiones de juego.

    // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 #include "GameLiftServerGameMode.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); AGameLiftServerGameMode::AGameLiftServerGameMode() : 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 AGameLiftServerGameMode...")); } void AGameLiftServerGameMode::BeginPlay() { Super::BeginPlay(); #if WITH_GAMELIFT InitGameLift(); #endif } void AGameLiftServerGameMode::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. ServerParametersForAnywhere.m_processId = TCHAR_TO_UTF8( *FText::Format( FText::FromString("ProcessId_{0}"), FText::AsNumber(std::time(nullptr)) ).ToString() ); } 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); } 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, 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, GameLift 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. GameLift 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 GameLift we are indeed going to shutdown. ProcessParameters->OnTerminate.BindLambda([=]() { UE_LOG(GameServerLog, Log, TEXT("Game Server Process is terminating")); GameLiftSdkModule->ProcessEnding(); }); //This is the HealthCheck callback. //GameLift 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. GameLift 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 GameLift where to find game session log files. //At the end of a game session, GameLift uploads everything in the specified //location and stores it in the cloud for access later. TArray<FString> Logfiles; Logfiles.Add(TEXT("GameServerLog/Saved/Logs/GameServerLog.log")); ProcessParameters->logParameters = Logfiles; //The game server calls ProcessReady() to tell GameLift 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 }

Integración del mapa de juego del cliente

El mapa inicial del juego contiene una lógica de esquema y elementos de interfaz de usuario que ya incluyen un código básico para solicitar sesiones de juego y utilizar la información de la conexión para conectarse a una sesión de juego. Puede utilizar el mapa tal como está o modificarlo según sea necesario. Utilice el mapa inicial del juego con otros recursos del juego, como el proyecto de plantilla Tercera persona proporcionado por Unreal Engine. Estos recursos están disponibles en el navegador de contenido. Puedes usarlos para probar los flujos de trabajo de despliegue del plugin o como guía para crear un servicio de backend personalizado para tu juego.

El mapa inicial tiene las siguientes características:

  • Incluye la lógica tanto para una flota de Anywhere como para una EC2 flota gestionada. Al gestionar su cliente, puede elegir conectarse a cualquiera de las dos flotas.

  • La funcionalidad del cliente incluye buscar una sesión de juego (SearchGameSessions()), crear una nueva sesión de juego (CreateGameSession()) y unirse a una sesión de juego directamente.

  • Obtiene un ID de jugador único del grupo de usuarios de Amazon Cognito del proyecto (forma parte de una solución de Anywhere implementada).

Uso del mapa inicial del juego
  1. En el editor de UE, abra la página Configuración, mapas y modos del proyecto y expanda la sección Mapas predeterminados.

  2. En el mapa de inicio del editor, selecciona StartupMap "» en la lista desplegable. Puede que necesite buscar el archivo, que se encuentra en ... > Unreal Projects/[project-name]/Plugins/Amazon GameLift Plugin Content/Maps.

  3. En el mapa predeterminado del juego, selecciona el mismo "StartupMap" en la lista desplegable.

  4. Para ver el mapa predeterminado del servidor, selecciona "ThirdPersonMap». Este es un mapa predeterminado incluido en el proyecto de juego. Este mapa está diseñado para dos jugadores del juego.

  5. Abra el panel de detalles del mapa predeterminado del servidor. Defina GameMode la anulación como «Ninguna».

  6. Expanda la sección Modos predeterminados y establezca Modo de juego del servidor predeterminado global en el modo de juego que actualizó para la integración del servidor.

Una vez que hayas realizado estos cambios en tu proyecto, estarás listo para crear los componentes del juego.

Package los componentes de su juego

Para empaquetar las versiones del servidor y del cliente del juego
  1. Creación de nuevos archivos de destino de servidor y cliente

    1. En la carpeta de proyectos del juego, diríjase a la carpeta Fuente y busque los archivos Target.cs.

    2. Copie el archivo [project-name]Editor.Target.cs en dos archivos nuevos denominados [project-name]Client.Target.cs y[project-name]Server.Target.cs.

    3. Edite cada uno de los archivos nuevos para actualizar el nombre de la clase y los valores del tipo de destino, como aparece a continuación:

    UnrealProjects > MyGame > Source > MyGameClient.Target.cs // Copyright Epic Games, Inc. All Rights Reserved. using UnrealBuildTool; using System.Collections.Generic; public class MyGameClientTarget : TargetRules { public MyGameClientTarget(TargetInfo Target) : base(Target) { Type = TargetType.Client; DefaultBuildSettings = BuildSettingsVersion.V2; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; ExtraModuleNames.Add("MyGame"); } }
    UnrealProjects > MyGame > Source > MyGameServer.Target.cs // Copyright Epic Games, Inc. All Rights Reserved. using UnrealBuildTool; using System.Collections.Generic; public class MyGameServerTarget : TargetRules { public MyGameServerTarget(TargetInfo Target) : base(Target) { Type = TargetType.Server; DefaultBuildSettings = BuildSettingsVersion.V2; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; ExtraModuleNames.Add("MyGame"); } }
  2. Actualice el archivo .Build.cs.

    1. Abra el archivo .Build.cs para su proyecto. Este archivo se encuentra en UnrealProjects/[project name]/Source/[project name]/[project name].Build.cs.

    2. Actualice la clase ModuleRules como aparece en el siguiente ejemplo de código.

      public class MyGame : ModuleRules { public GameLiftUnrealApp(TargetInfo Target) { PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); bEnableExceptions = true; if (Target.Type == TargetRules.TargetType.Server) { PublicDependencyModuleNames.AddRange(new string[] { "GameLiftServerSDK" }); PublicDefinitions.Add("WITH_GAMELIFT=1"); } else { PublicDefinitions.Add("WITH_GAMELIFT=0"); } } }
  3. Vuelva a compilar la solución del proyecto de juego.

  4. Abra el proyecto de juego en una versión original del editor de Unreal Engine.

  5. Realice el siguiente procedimiento tanto para el cliente como para el servidor:

    1. Elija un destino. Diríjase a Plataformas, Windows y seleccione una de las siguientes opciones:

      • Servidor: [your-application-name]Server

      • Cliente: [your-application-name]Client

    2. Iniciar la compilación. Diríjase a Plataforma, Windows, Proyecto de paquete.

Cada proceso de empaquetado genera un archivo ejecutable: [your-application-name]Client.exe o [your-application-name]Server.exe.

En el complemento, establezca las rutas a los archivos ejecutables de compilación del cliente y del servidor en su estación de trabajo local.

Paso 3: Conexión a una flota de Anywhere

En este paso, tendrá que designar la flota de Anywhere que desee utilizar. Una flota de Anywhere define un conjunto de recursos informáticos, que se pueden ubicar en cualquier lugar para el alojamiento de servidores de juegos.

  • Si la AWS cuenta que utilizas actualmente tiene flotas de Anywhere, abre el campo desplegable del nombre de la flota y elige una flota. Este menú desplegable solo muestra las flotas de Anywhere de la AWS región para el perfil de usuario activo actualmente.

  • Si no hay ninguna flota existente, o si desea crear una nueva, seleccione Crear nueva flota Anywhere e introduzca un nombre para la flota.

Una vez que hayas elegido una flota de Anywhere para tu proyecto, Amazon GameLift verifica que el estado de la flota esté activo y muestra el identificador de la flota. Puedes hacer un seguimiento del progreso de esta solicitud en el registro de resultados del editor de Unreal.

Paso 4: Registro de su estación de trabajo

En este paso, se registrará su estación de trabajo local como recurso informático en la nueva flota de Anywhere.

Para registrar su estación de trabajo como Anywhere Compute
  1. Especifique un nombre de equipo para la máquina local. Si añade más de un recurso informático a la flota, los nombres deben ser únicos.

  2. Proporcione una dirección IP para su máquina local. El valor predeterminado de este campo es la dirección IP pública de su máquina. También puedes usar localhost (127.0.0.1) siempre que ejecutes el cliente y el servidor del juego en la misma máquina.

  3. Elija Registrar computación. Puedes hacer un seguimiento del progreso de esta solicitud en el registro de resultados del editor de Unreal.

En respuesta a esta acción, Amazon GameLift comprueba que puede conectarse al equipo y devuelve información sobre el equipo recién registrado. También crea los argumentos de consola que los ejecutables de tus juegos necesitan al inicializar la comunicación con el servicio de Amazon GameLift .

Paso 5: Generación del token de autenticación

Los procesos del servidor de juegos que se ejecutan en tu ordenador de Anywhere necesitan un token de autenticación para realizar llamadas al GameLift servicio. El complemento genera y almacena automáticamente un token de autenticación para la flota de Anywhere cada vez que inicia el servidor de juegos desde el complemento. El valor del token de autenticación se almacena como un argumento de línea de comandos, que el código del servidor puede recuperar en tiempo de ejecución.

No tiene que realizar ninguna acción en este paso.

Paso 6: Lanzamiento del juego

En este punto, has completado todas las tareas necesarias para lanzar y jugar tu juego multijugador en una estación de trabajo local con Amazon GameLift.

Para jugar a tu juego alojado
  1. Lance el servidor de juegos. El servidor del juego notificará a Amazon GameLift cuando esté listo para organizar sesiones de juego.

  2. Lance el cliente de juegos y utilice la nueva funcionalidad para iniciar una nueva sesión de juego. Esta solicitud se envía a Amazon a GameLift través del nuevo servicio de backend. En respuesta GameLift, Amazon llama al servidor del juego, que se ejecuta en tu máquina local, para iniciar una nueva sesión de juego. Cuando la sesión de juego esté lista para aceptar jugadores, Amazon GameLift proporcionará la información de conexión para que el cliente del juego se una a la sesión de juego.