I see, so it sounds like although you’ve filtered out the transforms for the parts of the mesh that you aren’t interested in you still get the notifies for all of the parts of the mesh. Is that correct?
If you can make engine code changes, you could do what you want by implementing an IAnimEventsFilterContext and then injecting that into all the sampled notifies each frame via a custom IGraphMessage. If you look in FAnimNotifyEventReference, you’ll see that contains an array of IAnimNotifyEventContextDataInterface. The idea is that for each sampled notify, we can inject some form of custom data that can then be pulled out of the notify later. And you can use an IGraphMessage implementation to add the context data to the notify when it’s sampled.
A good example of this would be FBlendStackAnimEventsFilterScope and FBlendStackAnimEventsFilterContext. FBlendStackAnimEventsFilterScope is used within FAnimNode_BlendStack_Standalone::UpdateAssetPlayer so that any notify that is sampled under that point in the graph has an FBlendStackAnimEventsFilterContext added to it.
You would want to do similar, but for every notify sampled within the graph. And we do something like that with UE::Anim::FAnimSyncGroupScope which is added before the root node of the graph is updated in FAnimInstanceProxy::UpdateAnimation_WithRoot.
This code is a bit obscure so I wanted to test this out. I got something working as follows:
`class FOwningAnimGraphAnimEventsFilterContext : public IAnimEventsFilterContext
{
public:
FOwningAnimGraphAnimEventsFilterContext() {}
FOwningAnimGraphAnimEventsFilterContext(const FString& InOwningAnimInstanceName);
virtual bool ShouldFilterNotify(const FAnimNotifyEventReference& InNotifyEventRef) const override;
const FString OwningAnimInstanceName;
};
class FOwningAnimGraphAnimEventsFilterScope : public IGraphMessage
{
DECLARE_ANIMGRAPH_MESSAGE(FOwningAnimGraphAnimEventsFilterScope);
public:
FOwningAnimGraphAnimEventsFilterScope(const FString& InOwningAnimInstanceName);
virtual TUniquePtr MakeUniqueEventContextData() const override;
private:
const FString OwningAnimInstanceName;
};`And then you can use the filter scope in FAnimInstanceProxy::UpdateAnimation_WithRoot:
`// Anything syncing within this scope is subject to sync groups.
// We only enable syncing here for the main instance or post process instance
// We also fall back to enabling this sync scope if there is not one already enabled (there must always be one)
const bool bEnableSyncScope = GetAnimInstanceObject() == GetSkelMeshComponent()->GetAnimInstance() ||
GetAnimInstanceObject() == GetSkelMeshComponent()->GetPostProcessInstance() ||
InContext.GetMessageUE::Anim::FAnimSyncGroupScope() == nullptr;
UE::Anim::TOptionalScopedGraphMessageUE::Anim::FAnimSyncGroupScope Message(bEnableSyncScope, InContext, InContext);
// New code start
UE::Anim::TOptionalScopedGraphMessageUE::Anim::FOwningAnimGraphAnimEventsFilterScope OwningAnimGraphMessage(true, InContext, GetAnimInstanceName());
// update all nodes
if(InRootNode == RootNode)
{
// Call the correct override point if this is the root node
UpdateAnimationNode(InContext);`Then, if you have a natively implemented Notify you should be able to grab the context data from the FAnimNotifyEventReference that’s passed into your Received_Notify method. It’s a bit clunky, but I think this would give you what you need. And it’s a better option than iterating over all the sequence player nodes on all the anim instances to find the correct one.