jwindgassen / UnrealYAML

A UnrealEngine-Wrapper for the yaml-cpp Library
Other
25 stars 13 forks source link

Read into nested structs with arrays #12

Open Arise opened 10 months ago

Arise commented 10 months ago

Can I read from an YAML file that contains multiple nested structs with arrays?

I tried to load YAML from file and only the root Image is loaded, but the Clothes array is not. Is this a limitation of the plugin or I just did some error in my loader/processing?

Example below, can I read this into a Cloth struct that has an array of ClothDetails?

Image: Clothes.png
Clothes:
    - Cloth:
        Type: Hat
        Image: hat.png
    - Cloth:
        Type: Shoes
        Image: shoes.png
    - Cloth:
        Type: Pants
        Image: pants.png
    - Cloth:
        Type: Gloves
        Image: gloves.png

I had my structs as:

USTRUCT(BlueprintType)
struct MYPROJECT_API FClothDetailsStruct {
    GENERATED_BODY()

    UPROPERTY(BlueprintReadWrite)
    FString ClothType;

    UPROPERTY(BlueprintReadWrite)
    FString Image;

};

USTRUCT(BlueprintType)
struct MYPROJECT_API FClothStruct {
    GENERATED_BODY()

    UPROPERTY(BlueprintReadWrite)
    FString Image;

    UPROPERTY(BlueprintReadWrite)
    TArray<FClothDetailsStruct> Clothes;

};
jwindgassen commented 10 months ago

To parse a YAML Node into an Unreal Struct/Class, you can use the ParseNodeIntoStruct function, which is defined in Parsing.h. It takes the Node you want to parse and a reference to the USTRUCT/UCLASS you want to fill. It will return true when all field could be successfully parsed. The ConvertToStruct test uses this function, although the majority of the work is defining the USTRUCT, not the call itself.

The problem of the code you provided is, however, that your USTRUCTs do not map onto the given YAML correctly. If you convert the YAML to JSON, you can see, that FClothDetailStruct is wrapped in another Object, where an Cloth key maps onto FClothDetailStruct. This wrapper struct is then the type of the array elements:

{
    "Image": "Clothes.png",
    "Clothes": [
        {
            "Cloth": {
                "Type": "Hat",
                "Image": "hat.png"
            }
        },
        {
            "Cloth": {
                "Type": "Shoes",
                "Image": "shoes.png"
            }
        },
        {
            "Cloth": {
                "Type": "Pants",
                "Image": "pants.png"
            }
        },
        {
            "Cloth": {
                "Type": "Gloves",
                "Image": "gloves.png"
            }
        }
    ]
}

If you want your YAML to work with your USTRUCTs, it must look like this:

Image: Clothes.png
Clothes:
    - Type: Hat
      Image: hat.png
    - Type: Shoes
      Image: shoes.png
    - Type: Pants
      Image: pants.png
    - Type: Gloves
      Image: gloves.png

YAML syntax can be a bit funky at times, so I often use this trick of converting it to JSON if I think there might be a formatting issue