Need Help: access a property in child struct recursively

I’ve been stuck on an issue for a few weeks and looking for help on where I might be going wrong in my c++ code.

Objective
The goal is to get or set a property of a child struct inside a parent struct using dot notation.

The parent struct will have a property containing an array of child structs.

The code will need to work on any struct with a mix of property types.

I’m using Unreal version 5.0.3 on Windows.

Error
The error occurs when getting or setting a property on the child struct.

Struct Example
The struct has an “items” property that is an array containing two child structs:

+- Parent Struct -------------------+
|   color: "red"                    |
|   items: array of structs         |
|          +--child struct ----+    |
|          | type: “toy”       |    |
|          +-------------------+    |
|          +--child struct-----+    |
|          | type: “food”      |    |
|          +-------------------+    |
+-----------------------------------+

Code
I want to access the “type” property in the child struct recursively.

I use dot notation to access the property, example: “items.0.type”.

Here’s a stripped down version of the c++ code to access the child struct property. Recursion and dot notation code removed for clarity.

Error happens on line 35.

(This is just a code snippet so ignore any unrelated issues as the full code compiles)

1 static bool SetStructPropertyViaPath(FProperty* Property, void* StructPtr, FString FieldName, int32 FieldArrayIndex) {
2
3 FStructProperty* StructProperty = CastField<FStructProperty>(Property);
4
5  // Walk the structs' properties
6  for (TFieldIterator<FProperty> PropertyIt(StructProperty->Struct); PropertyIt; ++PropertyIt)
7  {
8    // Never assume ArrayDim is always 1
9    for (int32 ArrayIndex = 0; ArrayIndex < PropertyIt->ArrayDim; ArrayIndex++)
10    {
11      // This grabs the pointer to where the property value is stored
12      void* ValuePtr = PropertyIt->ContainerPtrToValuePtr<void>(StructPtr, ArrayIndex);
13
14      if (*PropertyIt->GetAuthoredName() == FieldName)
15      {
16
17        FStructProperty* InnerStructProperty = CastField<FStructProperty>(*PropertyIt);
18        FArrayProperty* InnerArrayProperty = CastField<FArrayProperty>(*PropertyIt);
19
20        if (InnerStructProperty) {
21          // return field value
22          return ParseProperty(*PropertyIt, ValuePtr, StructPtr, FieldName);
23
24          // Or recurse
25          return SetStructPropertyViaPath(*PropertyIt, ValuePtr, FieldName);
26
27        } else if (InnerArrayProperty) {
28
29          FScriptArrayHelper Helper = FScriptArrayHelper::CreateHelperFormInnerProperty(InnerArrayProperty->Inner, StructPtr);
30
31          ////////////////////////////////
32          // ERROR HERE:
33          //   Crashes or returns an incorrect value 
34          //   Helper doesn't seem to point to the child struct
35          UE_LOG(LogTemp, Warning, TEXT("Array Elements: %i"), Helper.Num());
36          
37          if (Helper.IsValidIndex(FieldArrayIndex)) {
38
39            // return field value
40            return ParseProperty(InnerArrayProperty->Inner, Helper.GetRawPtr(FieldArrayIndex), ValuePtr);

UE_LOG(LogTemp, Warning, TEXT("Array Elements: %s"), Helper.Num());

The function is expecting a string indicated by the ‘%s’. You’re telling the formatter you want a string replacing the ‘%s’.
Helper.Num() returns an int32 so replace the ‘%s’ with ‘%i’ so it will expect an integer.

I don’t think that’s the core issue, it’s more about how to properly access the property.

The core issue is the array helper doesn’t have the right data pointing to the struct property.

I’ll update the code example with your suggestion for clarity.

It might not be every error but it would crash your program.

You should use ValuePtr and not StructPtr when constructing the array helper.