I want to inject my own menu entry into the UAsset menu, which is shown when right clicking any UAsset inside the editor. This menu entry must be shown for all UObjects.
I have tried to register new actions for a UObject using:
Thanks, I got it working. I don’t know why it wasn’t working using lambdas as I was doing something very similar to Blutility but it works in the new format.
I figured out what the problem was, it was not the lambda.
The part that says “Asset” had to be changed to “CommonAssetActions” to make the menu entry show up. You can not write any name here as the editor will just skip the entry entirely and silently.
For someone looking for more details, there are several things that can go wrong when implementing a menu extender.
First, as @Roy_Wierer.Seda145 mentioned, you can’t make up an arbitrary name for your extender’s ExtensionHook parameter. It has to be predefined by unreal (or probably another extension that runs before you, but I didn’t verify this). For instance, “Asset” won’t work but “CommonAssetActions” will since the latter is predefined by unreal.
You can figure out what those predefine names are by enabling the engine’s developer tool. See this thread.
Second, if you use CreateSP to creating the delegate for AddMenuExtension, you have to remember that CreateSP creates a weak reference to the user object (the suffix SP is confusing as it leads people to think it actually creates a strong shared pointer), and thus when the shared pointer to your extender implementation class goes out of scope, the delegate will become unbound, leading to the extension callback to not be called at all.
An example in this post solves this by storing the shared pointer inside the module instance itself. See the following lines from their example:
// Extension variable contains a copy of selected paths array, you must keep Extension somewhere to prevent it from being deleted/garbage collected!
Extension = MakeShareable(new FContentBrowserMenuExtension(Path));
But I think the better way is to just use a lambda and capture the shared pointer by copy. Here is my approach: