How can I get the currently edited UAnimAsset from my plugin?

I am writing a plugin to perform an operation over animation sequences (basically search for a specific pattern in the animation and create notifies on each match). I am trying to implement it as a toolbar button added to the Persona editor toolbar, and so far I have been able to add such button that calls my code using an FExtender and a custom TCommands class. The problem is I am not able to find a way to retrieve the UAnimAsset currently being edited in the Persona editor. I am using 4.13, and I realize that on 4.14 the AnimationEditor module was introduced, but in any case that wouldn’t seem to be of any help for me; AnimationEditor offers FAnimationEditorToolbarExtender, which appears to be an interface for extending the toolbar customized for the animation editor, but IIUC the only additional resource that would provide me with is an IAnimationEditor, which would only let me set the UAnimAsset being edited, not retrieve the current one. PersonaModule does not offer any API to this end and in the engine code the toolbar and menu extensions are always added by the managers of the Persona editor themselves, so they already have the reference to the edited UAnimAsset beforehand, or at least the FPersona object editing it.

I have been trying to think of alternative routes to achieve this, even if they are not the most robust, like trying to somehow retrieve the objects of the top level editor window (which I can assume it’s going to be the Persona editor when my button is clicked), possibly from GEditor, and maybe get to the FPersona object in some way, or querying for some global UObject that would lead me to the asset, but I have not been able to find any effective route.

Is there any way to achieve what I want, or something similar?

PS: As a backup plan, I could instead create an asset action in the contextual menu of UAnimSequence assets and perform my operation directly from the content browser, but it would really be more convenient for my use case to have it as a button or menu item or something within the Persona editor.


Here is more or less what my code looks like right now:

class FMyOpearationCommands : public TCommands<FMyOpearationCommands>
{
public:
	FMyOpearationCommands()
		: TCommands<FMyOpearationCommands>(...)
	{}
	virtual void RegisterCommands() override { UI_COMMAND(MyOperation, ...); }
	TSharedPtr<FUICommandInfo> MyOperation;
};

class FMyOperation
{
public:
	static FMyOperation& Get() { /* Get singleton instance... */ }
	static void Initialize();
	{
		/* Make singleton instance and register FMyOperationCommands */
		/* Called on plugin module load. */
	}
	static void Finalize()
	{
		/* Clear singleton instance and unregister FMyOperationCommands */
		/* Called on plugin module unload. */
	}
	FMyOperation()
		: m_personaToolbarExtensibilityManager()
		, m_extender(new FExtender)
		, m_commandList(new FUICommandList)
	{
		FPersonaModule& personaModule =
			FModuleManager::LoadModuleChecked<FPersonaModule>("Persona");
		m_personaToolbarExtensibilityManager = 
			personaModule.GetToolBarExtensibilityManager();
		m_personaToolbarExtensibilityManager->AddExtender(m_extender);
		BindCommands();
		m_extender->AddToolBarExtension(FName(TEXT("Asset")),
			EExtensionHook::After, m_commandList,
			FToolBarExtensionDelegate::CreateLambda(
				[this](FToolBarBuilder& ToolBarBuilder)
				{ /* Add tool bar section and button... */ }
			)
		);
	}
	virtual ~FMyOperation() { /* Unregister extender... */ }
private:
	static TSharedPtr<FMyOperation> Instance;
	TSharedPtr<FExtensibilityManager> m_personaToolbarExtensibilityManager;
	TSharedPtr<FExtender> m_extender;
	TSharedPtr<FUICommandList> m_commandList;
	void BindCommands()
	{
		m_commandList->MapAction( FMyOperationCommands::Get().MyOperation,
			FExecuteAction::CreateLambda([this]()
			{
				// PROBLEM IS HERE
				// How can I get the currently edited UAnimAsset 
				// in the implementation of the toolbar command?
			})
		);
	}
};

So I found the right way to go about this. It seems it is indeed easier from 4.14 with the AnimationEditor module, where you would resort to the IAnimationEditorModule interface and add a FAnimationEditorToolbarExtender delegate that would be called each time an editor is opened receiving the IAnimationEditor (from where you can retrieve the edited animation) and returning the appropriate FExtender.

In my case I use the extensibility manager of the persona module, as posted above, but instead of registering a singleton extender with AddToolBarExtension like I was doing, I added a delegate to the array returned by GetExtenderDelegates. In this case you receive the FUICommandList being used and and the array of objects being edited. Funny enough, due to the specific order in which things are done in FPersona (in 4.13 at least), this array of object does not include the animation asset. Also you don’t have a pointer to the editor, which is necessary if you want to do things like “show my button only in the animation mode”. Anyway, I got around by using the FAssetEditorManager, getting the primary editor of one of the recevied edited objects (which are mesh and skeleton) and hoping that has to be the right one.

FAssetEditorManager also offers an alternative route to solve the problem, by adding a delegate to one of its events (ideally OnAssetOpenedInEditor, but since 4.13 does not have that yet OnAssetEditorOpened could do) and adding the button to the editor tool bar once when you detect that an animation sequence has been opened for editing in Persona.