Skeletal animation not playing with a different UWorld

I’ve got a separately created UWorld with a skeletal mesh component which I’m using as a capture target for offscreen rendering.

The problem is I seem to be unable to get an animation to play on the mesh while it is registered to my created UWorld. However, if I register the mesh to the main game world then the animation plays just fine, so I’m assuming my code for triggering the animation is correct.

Basically my code looks like this:

mWorld = UWorld::CreateWorld(EWorldType::Game, false, NAME_None, nullptr, true);
prim->RegisterComponentWithWorld(mWorld);
prim->PlayAnimation(anim, true);

This leads me to believe there is a problem with ticking somewhere, but I’ve manually tried to tick the skeletal mesh component with:

prim->TickComponent(deltaSeconds, LEVELTICK_All, nullptr);

But this doesn’t have any effect either. Of course if I tick the component while it’s registered to the main game world, the animation plays twice as fast, so TickComponent() is working too.

I did notice that if I try to forcibly tick my UWorld, I end up with a crash in FTickTaskSequencer::StartFrame(), so that’s probably not the right route to go down.

Any suggestions on what I might be missing or where I could be going wrong?

I think you’re right in that ticking is missing, you should tick the world, then it will tick component with it. You can check how we tick our viewport worlds.

void FAnimationViewportClient::Tick(float DeltaSeconds) 

PreviewScene->GetWorld()->Tick(LEVELTICK_All, DeltaSeconds);

I did notice that if I try to forcibly tick my UWorld, I end up with a crash in FTickTaskSequencer::StartFrame(),

I’m not sure why this should be the case. We do tick the world for all our viewport levels. You can see how we create the world and scene. I do think you’d need scene to render. FPreviewScene

Thanks,

–Lina,

Hi,

We think this post contains useful information which we would like to share with our public UE4 community. With your approval, we would like to make a copy of this post on the public AnswerHub which includes the discussion but strips out your username and company name. Please let us know if you are okay with this.

Thanks!

I found a solution for this today, and it turned out to be rather simple.

When a skeletal mesh component is ticked, the animation curves are indeed evaluated and the bones are updated. This also sets a dirty flag (bRenderDynamicDataDirty) which tells the renderer that the mesh’s dynamic data needs to be updated as well. Without updating the dynamic data, the skeletal mesh is always rendered in the reference pose.

To update the dynamic data, all that is needed is to call an additional function after TickComponent:

for (UActorComponent *comp : ListOfComponentsToUpdate) {
	comp->TickComponent(deltaSeconds, LEVELTICK_All, nullptr);
	comp->DoDeferredRenderUpdates_Concurrent();
}

It looks like a full world tick goes through this same process, doing the render updates just before the beginning of frame rendering. Currently (as of UE4.9 at least), Unreal doesn’t support ticking of a subworld contained within a component of the main world, so the above solution seems to be the easiest workaround.