Get index of element changed in array

Hey all,

I’m using an override on the base method PostEditChangeProperty to find whenever a property has been changed on an actor, but on this actor I have an array of structs, and when a property in one of the structs changes, I need to know which struct changed, for which I can’t find any way to identify which struct in the array using the FPropertyChangedEvent parameter.

Currently I’m up to here:

Super::PostEditChangeProperty(e);
FName PropertyName = (e.Property != NULL) ? e.Property->GetFName() : NAME_None;
FName InnerFieldName = e.MemberProperty->GetFName();
uint32 ChangeType = e.ChangeType;
TArray<FField*> Fields;
e.MemberProperty->GetInnerFields(Fields);
UStruct* Struct = Fields[0]->GetOwnerStruct();

I’ve noticed the MemberProperty references the array the property is in, so I tried using the GetOwnerStruct, but it doesn’t seem to get what I’m really after, nor can I cast it to my struct…

Suggestions?

Hello! Do you try GetArrayIndex method of FPropertyChangedEvent?

I don’t know how I didn’t see that method in the documentation… But just tried it, and while it works if the element changed is the array itself, but if it’s a property in the struct element, then the index returns something in the millions…

I’ve tried another idea, of putting another UPROPERTY on the struct called bStructChanged, set to false by default, then in the PostEditChangeProperty method, I’ve declared a FField* Field variable and looped through the linked list of properties provided by FField* until I reach the bStructChanged field.

At this point, I initialize an FBoolProperty* BoolProperty variable with a CastField on the Field variable from before, and if the cast is successful, I try calling SetPropertyValue on the BoolProperty and setting it true, then will later loop through the structs in the array to find the element where bStructChanged is true…

But, it looks like SetPropertyValue requires a pointer to the actual variable, which I don’t know which variable it is since I don’t know which struct it belongs to in the array lol.

FField* Field = e.Property;
FField* NextField = Field->Next;

while (NextField->GetFName() != "bStructChanged" && NextField->Next)
{
	NextField = NextField->Next;
}
if (NextField->GetFName() == "bStructChanged")
{
	FBoolProperty* BoolProperty = CastField<FBoolProperty>(NextField);
	if (BoolProperty)
		BoolProperty->SetPropertyValue(BoolProperty, true);
}

Ok solved this one by using a different method, instead of using PostEditChangeProperty, should have been using PostEditChangeChainProperty, which provides the array node the changed property is a member of, and so I can get the index of the array element that was changed by using the following code…

void UIOSystem::PostEditChangeChainProperty(FPropertyChangedChainEvent& e)
{
	Super::PostEditChangeChainProperty(e);
	int32 MemberNodeIndex = e.GetArrayIndex(e.PropertyChain.GetActiveMemberNode()->GetValue()->GetName());
	// rest of code here...
}
1 Like