UE4 | Inventario para multijugador n. ° 2 | Conectar Blueprint a C ++




Modo de juego En un artículo anterior, hablé sobre cómo crear un DataAsset y por qué es tan agradable y conveniente. Aquí veremos cómo acceder al DataAsset , más precisamente a los datos asignados a él, desde Blueprint y C ++ .


En el camino, responderemos la pregunta de acceder a cualquier Blueprint desde C ++ .




Con la interacción Blueprints , todo es bastante transparente.
Debido al hecho de que hemos cerrado el acceso directo a nuestra base de datos, no podemos acceder simplemente desde Blueprint . Presta atención a protegido: en el código a continuación.


protected: /* This is the main Database for all Items. It contains constant common variables */ UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "ItemsDatabase") TMap<FGameplayTag, FItemsDatabase> ItemsDataBase; 

Es decir nuestro repositorio será visible solo en clases heredadas, y esto es bueno, porque tenemos funciones escritas para llamar con seguridad a los datos.


 /* Used in the widget */ UFUNCTION(BlueprintCallable, Category = "ItemDatabase") FORCEINLINE UTexture2D * GetItemIconTexture(const FGameplayTag & ItemNameTag) const; 

BlueprintCallable solo significa que esta función se puede usar en Blueprint . Si leyó el artículo anterior , probablemente notó que otras funciones de llamar a este atributo no tienen. Esto se hizo solo porque los datos que llamaron actualmente no eran necesarios en Blueprint . Si alguien no necesita saber algo, no tenemos prisa por denunciarlo.


El siguiente paso es crear una variable en cualquier tipo de Blueprint de la base de datos que creamos (en mi caso, es BP_DreampaxItemsDataAsset ).


Después de eso, extraemos fácilmente la textura asignada.




Ahora considere cómo acceder a la información en C ++ .
No podemos simplemente referirnos a la clase DreampaxItemsDataAsset , porque no contiene ninguna información. Necesitamos obtener acceso a BP_DreampaxItemsDataAsset .


Hay dos métodos principales para llegar a Blueprint .
Primero, considere un método de conexión inconveniente usando la muleta ConstructorHelpers. En este caso, acceso a la textura.


 ASHUD::ASHUD(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { /* You can use the FObjectFinder in C++ to reference content directly in code. Although it's advisable to avoid this and instead assign content through Blueprint child classes. */ static ConstructorHelpers::FObjectFinder<UTexture2D> HUDCenterDotObj(TEXT("/Game/UI/HUD/T_CenterDot_M.T_CenterDot_M")); CenterDotIcon = UCanvas::MakeIcon(HUDCenterDotObj.Object); } 

El ejemplo está tomado del maravilloso proyecto EpicSurvivalGameSeries , perfecto para aprender Multijugador en C ++ . El autor se propuso mostrar tantos métodos y técnicas de programación de un juego en C ++ como sea posible.


¿Por qué este método es inconveniente? El mismo problema que con DataTable : si cambia el nombre o la ubicación del Blueprint , no se encontrará el archivo.


El más preferible es el método en el que declaramos una variable en el archivo de encabezado para su asignación posterior ya en el Blueprint heredado. Para el ejemplo anterior, podría verse así:


  UPROPERTY(EditDefaultsOnly, Category = "AimPointer") FCanvasIcon CenterDotIcon; 

Mucho más fácil, ¿verdad?
Asignación de textura



Ahora, sabiendo cómo acceder a cualquier Blueprint , podemos conectar fácilmente nuestra base de datos.


 UCLASS() class ADreampaxGameMode : public AGameMode { GENERATED_BODY() public: ADreampaxGameMode(const FObjectInitializer & ObjectInitializer); ///////////////////////////////////////////////////////////////////////////// //Data Bases ///////////////////////////////////////////////////////////////////////////// public: /* Connect data base in BP for items*/ UPROPERTY(EditDefaultsOnly, Category = "Database") class UDreampaxItemsDataAsset * DreampaxItemsDataAsset; FORCEINLINE UDreampaxItemsDataAsset * GetDreampaxItemsDataAsset() const; 

Una pequeña digresión para los no profesionales sobre la declaración de variables

Como una persona que no está familiarizada con C ++ , rompí muchas copias, tratando de descubrir cómo declarar las variables personalizadas correctamente.


Si el objetivo es declarar una variable de la clase que creamos, como


 UDreampaxItemsDataAsset * DreampaxItemsDataAsset; //  class UDreampaxItemsDataAsset * DreampaxItemsDataAsset; 

Yo personalmente no entendí por un tiempo cuándo usar la clase y cuándo no.


Todo resultó ser dolorosamente simple.


  1. Si no configura la clase , debe incluir #include "Data / DreampaxItemsDataAsset.h" , que contiene la declaración de esta clase.
  2. Si configura la clase , #include "Data / DreampaxItemsDataAsset.h" ya se puede hacer en .cpp .
  3. Y una opción más del párrafo anterior, si necesita declarar muchas variables de esta clase a la vez. Inmediatamente después de todo #include, pre-declare nuestra clase de clase UDreampaxItemsDataAsset; , y luego declara las variables sin el prefijo de clase .

¿Cuál de estos métodos es correcto? No puedo presumir decirlo. Si alguien explica, te lo agradeceré.


Creamos una variable en la clase C ++ ADreampaxGameMode , ya que solo es visible para el servidor, y todo lo relacionado con la generación de objetos debe pasar solo por el servidor. Esta clase es la principal para BP_DreampaxGameMode , donde conectamos nuestro BP_DreampaxItemsDataAsset .


BP_DreampaxItemsDataAsset Connection
BP_DreampaxItemsDataAsset Connection

Ahora se puede usar todo el poder de C ++ para trabajar con los datos de nuestra base de datos.


En el próximo artículo (¡finalmente!) Hablaremos sobre la creación de inventario y descubriremos por qué no podemos prescindir del DataAsset ya creado.


Si tiene preguntas o sugerencias para revelar algún aspecto con más detalle, escriba los comentarios.

Source: https://habr.com/ru/post/es418951/


All Articles