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: 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.
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) { 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?
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);
Una pequeña digresión para los no profesionales sobre la declaración de variablesComo 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;
Yo personalmente no entendí por un tiempo cuándo usar la clase y cuándo no.
Todo resultó ser dolorosamente simple.
- Si no configura la clase , debe incluir #include "Data / DreampaxItemsDataAsset.h" , que contiene la declaración de esta clase.
- Si configura la clase , #include "Data / DreampaxItemsDataAsset.h" ya se puede hacer en .cpp .
- 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 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.