How to add external object to Actor Detail Panel

I have an actor with an TArray<UObject*> as a UPROPERTY() (No meta)

I want to display each object’s exposed properties in the owning actors details panel. Similar to if you had a TArray of a struct on an actor.

I already have a custom category row on the actors detail customization.

This is what I have so far but it doesn’t work.

In the details customization cpp

void MyActotDetailsPanel::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
IDetailCategoryBuilder& CustomCategory = DetailBuilder.EditCategory("Custom");
TArray<TWeakObjectPtr<UObject>> SelectedActors;
	TArray<UObject*> Objects;
	for(auto& ActorBeingCustomized : Actors)
		if(AMyActor* MyActor = Cast<AMyActor>(ActorBeingCustomized))

When I do this, there is a new default name widget created but it just says “Object” and the default value widget is empty.

From what I understand (mind you I’m still new to Sate too), the GetObjectsBeingCustomized function returns the Object to which you are attaching your Slate module to.

For Example, I’m using it to get the owning Actor that holds a Component (I attached my Slate module to the component) which I’m customizing. The GetObjectsBeingCustomized function in this case returns to me the Owning object which I use to access another component inside of it.

Here is the documentation on it:

I’m unfortunately not sure as to how to help you in your problem specifically, as I said I’m still new at this, but hopefully this clarifies a bit why your current approach might not be working?

1 Like

Thanks for the reply!

I ended up working around this by using a couple property meta specifiers. Albeit it is NOT an ideal solution as it comes with it’s own problems which I will explain later.

UCLASS(EditInlineNew) will change the property in the property window to be Created from the TSubClassOf that you select rather than requiring a reference to the object itself. This was great! However, there is a gotcha.

The gotcha is garbage collection :slight_smile:

Lets say you have an array of TSubClassOf and you want the user to create these on the object in the editor using the EditInlineNew meta specifier. The default slate button widgets that get created for TArray will work reliably on time for object creation. Meaning when I hit the little plus button for the array, my object constructor runs and code in the OnConstruct override will be reliable.

When you remove the array member, instead of immediately deleting the object it is instead removed from the array… Meaning your object now has no outer and is actually just waiting for GC to come by. manually trigger a GC doesn’t remove the Object either, I’ve found that only after saving does the object actually get destructed. So for cleanup code I would normally write in the destructor override of UObject I can no longer rely on.

I worked around this by adding a property customization to a struct in the Object and then adding a button that will forceably delete the object.

Something else I’ve noticed that was quite annoying too. Object type customization overrides do NOT display when UObjects are UPROPERTY() members of another object when using EditInlineNew - However, their property type customizations WILL be used. So for all the customizations I wanted to show up I had to wrap the data members in a struct and then apply a prop customization to that.

Quite complicated an annoying. If the object customization would have just worked with EditInlineNew I would be in a much better place. I’m unsure if that is a bug or intentional. I’ve noticed that Property handles for Arrays and Maps have their own issues and workaround regarding customizations and reflection as a whole so it’s probably tangentally related to that.

Hope this helps someone!