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);