Spawning a mesh during an animation using C++

Having an skeletal mesh animation I wanted to spawn a static mesh and attach it to the socket of skeletam mesh.

First idea

Just create UPROPERTY() UStaticMeshComponent* MeshComponent; and allow it to be modified in the editor, so that any1 can pick proper mesh per animation.

tl;dr: it simply was crashing at some point (it was probably when it was attached to a different component but I can’t remember now). Could it possibly be that due to notification not having World reference it won’t create attachable components?

Second idea idea - construct static mesh component

UAnimNotifyState deriving class seemed to be a perfect candidate for just it because it features NotifyBegin and NotifyEnd methods - that seems to be super handy. There were 2 additional variables that I wanted to expose for change:

  • Mesh - so that you can tell what mesh should be spawned in the editor,
  • SocketName - so that you can also pick where the mesh should be bound to,

So I came with a class like this (you might find a more comfortable preview on GitHub):

#pragma once

#include "AnimNotifyWithComponent.generated.h"

/*
 * A solution based on manually creating UStaticMeshComponent in NotifyBegin function.
 * It work ingame no problem, but causes weird freeze in the editor anim preview.
 */
UCLASS()
class UAnimNotifyWithComponent : public UAnimNotifyState
{
	GENERATED_UCLASS_BODY()

	// Exposed Mesh property, so that mesh can be changed in the editor.
	UPROPERTY( EditAnywhere )
	UStaticMesh* Mesh;

	// Name of the socked, where the item will be placed.
	UPROPERTY( EditAnywhere )
	FName SocketName;
private:
	UPROPERTY()
	UStaticMeshComponent* MeshComponent;

	virtual void NotifyBegin( USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float TotalDuration ) override;

	virtual void NotifyEnd( USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation ) override;
};

You may find cpp file here.

In game it works just fine.

Issue

The code was not working in the editor prview. Once editor hits my notification (and calls NotifyBegin) it freezes for couple seconds giving an error on assigning reference to UPROPERTY(), here’s a dump:

UE4Editor-Core.dll!FWindowsPlatformStackWalk::StackWalkAndDump() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\core\private\windows\windowsplatformstackwalk.cpp:175]
UE4Editor-Core.dll!FDebug::EnsureFailed() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\core\private\misc\outputdevice.cpp:276]
UE4Editor-Core.dll!FDebug::OptionallyLogFormattedEnsureMessageReturningFalse() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\core\private\misc\outputdevice.cpp:385]
UE4Editor-Engine.dll!UActorComponent::RegisterComponent() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\components\actorcomponent.cpp:866]
UE4Editor-sample1-6656.dll!UAnimNotifyWithComponent::NotifyBegin() [c:\users\mlewandowski\documents\unreal projects\sample1\source\sample1\animnotifywithcomponent.cpp:59]
UE4Editor-Engine.dll!UAnimInstance::TriggerAnimNotifies() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\animation\animinstance.cpp:1213]
UE4Editor-Engine.dll!UAnimInstance::UpdateAnimation() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\animation\animinstance.cpp:433]
UE4Editor-Engine.dll!USkeletalMeshComponent::TickAnimation() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\components\skeletalmeshcomponent.cpp:479]
UE4Editor-Engine.dll!USkeletalMeshComponent::TickPose() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\components\skeletalmeshcomponent.cpp:588]
UE4Editor-Engine.dll!USkinnedMeshComponent::TickComponent() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\components\skinnedmeshcomponent.cpp:451]
UE4Editor-Engine.dll!USkeletalMeshComponent::TickComponent() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\runtime\engine\private\components\skeletalmeshcomponent.cpp:600]
UE4Editor-UnrealEd.dll!UDebugSkelMeshComponent::TickComponent() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.10\engine\source\editor\unrealed\private\animation\debugskelmeshcomponent.cpp:728]
(...)

Third approach - spawn AStaticMeshActor

Let me just note at the very begining that this is overkill :smiley: The idea was to:

  1. Spawn AStaticMeshActor that would be owned by Animation Skeletal Mesh owner.
  2. Hijack it’s StaticMeshComponent and attach it to the Skeletal Mesh.
  3. Destroy AStaticMeshActor because… I don’t need it for anything beside constructing StaticMeshComponen!

This idea is totally crazy, but implementation can be found in AnimNotifyWithActor class.

Issue

Here’s the thing: it works both for the editor and game. It’s the worst solution, yet it works the best.

The code

I decided to push all the code to a GitHub repository, feel free to see it there.