I got my self this:
USTRUCT(BlueprintType)
struct FARItemPickupCont
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY(EditAnywhere, Category = "Data Asset")
class UARItemsData* ItemData;
UPROPERTY(VisibleAnywhere, Category = "Asset Name")
FString ItemDataName;
UPROPERTY(EditAnywhere, Category = "Items To Pick")
TArray<int32> ItemsList;
inline bool operator==(const FARItemPickupCont& Other) const
{
return ItemData == Other.ItemData;
}
FARItemPickupCont()
: ItemsList()
{
ItemData = nullptr;
ItemDataName = FString("NoName");
};
};
USTRUCT(BlueprintType)
struct FARItemPickerContainer
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY(EditAnywhere, Category = "Items To Pick")
TArray<FARItemPickupCont> ListOfItems;
FARItemPickerContainer()
: ListOfItems()
{};
};
Nothing special. Now I try to create custom editor widget for FARItemPickerContainer.
I have widget, and the presentation part work, even if it is not pretty. What really gives me searious hitches, is inserting new elements to:
TArray<FARItemPickupCont> ListOfItems;
So far I tried to do it this way:
FARItemPickupCont newItemCont;
UARItemsData* tempItem = Cast<UARItemsData>(PickedAsset.GetAsset());
if (tempItem)
{
TArray<UObject*> OuterObjects;
StructPropHandle->GetOuterObjects(OuterObjects);
//GetChildHandle
FARItemPickerContainer* itemCont = nullptr;
UStructProperty* structProp = CastChecked<UStructProperty>(StructPropHandle->GetProperty());
if (structProp)
{
for (UObject* obj : OuterObjects)
{
// EditedObject = obj;
itemCont = structProp->ContainerPtrToValuePtr<FARItemPickerContainer>(obj);
}
}
if (itemCont)
{
newItemCont.ItemData = tempItem;
newItemCont.ItemDataName = tempItem->GetName();
itemCont->ListOfItems.AddUnique(newItemCont);
RegenerateComboBoxItems();
}
}
Get pointer to edited property, cast it to my type of property, and try to insert elements manually. It somewhat worked, but when I edit actor placed on level, and add new element, then deselect that actor and select it again, everything becomes invalid. I can only assume, that in fact I have never changed property on actor, and that is why it is not saved automatically.
I started digging and found
IPropertyHandleArray.
Long story short I tried to do something like that to test it out:
TSharedPtr<IPropertyHandle> propArray = StructPropHandle->GetChildHandle("ListOfItems");
TSharedPtr<FPropertyHandleArray> propArrHand = StaticCastSharedPtr<FPropertyHandleArray>(propArray->AsArray());
FPropertyAccess::Result res = propArrHand->AddItem();
uint32 numElems = 0;
propArrHand->GetNumElements(numElems);
but even though res == Success, numElems is always zero, so I bet there is no elements added to the array.
Then, I just thought I can just as well, try to get pointer to iarray in my struct.
TArray<FARItemPickupCont>* lololo = nullptr;
for (UObject* obj : OuterObjects)
{
lololo = tempAr->ContainerPtrToValuePtr<TArray<FARItemPickupCont>>(StructPropHandle->GetProperty());
}
But this happen:
UnrealType.h(344): Assertion failed: GetOuter()->IsA(UClass::StaticClass())
Now, I’m honestly out of ideas, of even when to start looking for solution in engine code. Any help is will be most valuable!