How to fix issues with cloth stretching?

I’ve added APEX clothing to a weapon.

The weapons in my game have two distinct meshes: one for first person, and one for third person (as in ShooterGame).

The clothing stretches quite a bit in the first person mesh, when the character moves or the camera rotates. But this doesn’t happens in the third person mesh. I made the 3rd person mesh visible in 1st person to verify this. Look:

Here I am running backwards, looking down. The bottom/left mesh is the 3rd person mesh, cloth works fine in it. The top/right mesh is the 1st person mesh, where you can see the cloth stretching.

I believe I know the cause: the 3rd person mesh is attached to the pawn’s collision component, and it ticks before physics work. The 1st person mesh is attached to the camera however, which ticks after physics work.

But I was unable to solve this issue. I’ve set the 1st person mesh tick group to TG_PostUpdateWork (so that it updates after the camera), but then the cloth simply doesn’t works (instead of stretching). Any other ideas?

Note: setting the tick group to TG_PostUpdateWork fixed some other off-by-one-frame issues I had on other weapons, so I think I’m on the right way. Just need to figure out how to update cloth on this tick group.

Bump… :slight_smile:

We had exact same issue, there something called tick groups. Objects are part of a specific group which ticking on specific rendering stage that this group belongs to. In other words it a setting allowing you to decide on which stage object is tick. You can set tick group for a object using SetTickGroup

Heres list of tick groups

Set tick group beyond one that cameraactor uses :slight_smile:

Unfortunately that didn’t work. I tried several tick groups (both for the actor and for the component), including the last tick group (TG_PostUpdateWork) and TG_PreCloth.

I also checked APlayerCameraManager and noticed it doesn’t defines a tick group! Also, it inherits directly from AActor, which has ticking disabled by default. I am intrigued.

…oh ok. The camera “ticks” on LevelTick.cpp line 1205 (in 4.1.1):

		// Update cameras last. This needs to be done before NetUpdates, and after all actors have been ticked.
		for( FConstPlayerControllerIterator Iterator = GetPlayerControllerIterator(); Iterator; ++Iterator )
		{
			APlayerController* PlayerController = *Iterator;			
			if (!bIsPaused || PlayerController->ShouldPerformFullTickWhenPaused())
			{
				PlayerController->UpdateCameraManager(DeltaSeconds);
			}
		}

Scrolling a few lines above that, I noticed all tick groups are ticked before the camera. So, setting tick groups will have no effect whatsoever.

Tried calling all sorts of tick functions I could find after the camera update:

void AShooterCharacter::OnCameraUpdate(const FVector& CameraLocation, const FRotator& CameraRotation)
{
	if (IsFirstPerson())
	{
		Tick(GDeltaTime);
		Mesh1P->TickAnimation(GDeltaTime);
		Mesh1P->TickComponent(GDeltaTime, ELevelTick::LEVELTICK_All, &Mesh1P->PrimaryComponentTick);
		Mesh1P->TickPose(GDeltaTime);
 		Mesh1P->TickClothing(GDeltaTime);
 		if (CurrentWeapon && CurrentWeapon->GetWeaponMesh1P())
 			CurrentWeapon->GetWeaponMesh1P()->TickClothing(GDeltaTime);
		PrimaryActorTick.ExecuteTick(GDeltaTime, ELevelTick::LEVELTICK_All, ENamedThreads::GameThread, FGraphEventRef());

...

}

But the cloth issue persists.

you tried my solution? :stuck_out_tongue:

Yes I did.

Actually, the group TG_PostUpdateWork ticks after the camera update. But still, setting that tick group doesn’t solves the cloth problem. Instead of stretching, the cloth simply doesn’t works (the cloth mesh stays perfectly still, as though it had no cloth defined).

Just tried adding it, after CameraUpdate()… still nothing :frowning:

Same behaviour: if tick group is TG_PostUpdateWork, cloth doesn’t works. If it’s any other tick group, cloth stretches.

Did you tried calling UpdateClothTransform and UpdateClothState?

Ok im out of ideas :stuck_out_tongue: we wanted to sync some objects with camera and we notice that objects are tick after camera making them follow with delay, setting them to TG_PostUpdateWork fixed that up

Yeah… your suggestions make sense, I’m also puzzled why it doesn’t works. Thanks anyway! :slight_smile:

Still no progress here…

Other functions added to OnCameraUpdate() that didn’t solve the problem:

	Mesh1P->UpdateClothState(GDeltaTime);
	Mesh1P->UpdateClothTransform();
	if (CurrentWeapon && CurrentWeapon->GetWeaponMesh1P())
	{
		CurrentWeapon->GetWeaponMesh1P()->UpdateClothTransform();
		CurrentWeapon->GetWeaponMesh1P()->UpdateClothState(GDeltaTime);
	}

PS: Mesh1P is currently set to the TG_PostUpdateWork tick group.

Hi ,

I apologize for not looking into this sooner. Is there any way you could send us the mesh for your weapon, with any APEX and/or PhysX components that it is using, so that we can take a look and see if we can determine what is happening with the cloth?

Thanks,

Hi , thanks for the reply. Sure I can send the mesh, but for this case I’m pretty sure the problem is in the code. Cloth works fine in third person mesh (and in the skeletal mesh editor), it only doesn’t works well (stretches) in first person view. Anyway, here are the files.

Edit: by third person and first person, I refer to the pawn’s mesh variant (I’m basing on ShooterGame) to which the weapon is attached. The character’s Mesh3P is attached to the character’s collision cylinder; and the character’s Mesh1P is attached to the player’s camera. The weapon is then attached to either one of those meshes.

Hi ,

Thank you for providing the files. We may need to get some additional information, but we wanted to run some tests on the mesh first to rule out a few possibilities.

Hi ,

I imported your weapon and cloth assets into an unmodified Shooter Game project and did not see the cloth stretching that you indicated. It looks like we will need to get a little more information. First though, if you bring the assets into a completely unmodified Shooter Game Project, do you still see the stretching?

What version of the Editor are you using, and is it compiled from source or running binaries from the Launcher? What changes, if any, have you made to the Shooter Game project?

Hi , sorry for the delay.

I did the test as you suggested, and on ShooterGame the cloth also stretches in first person view (in the shot, I am looking up/down rapidly):

It also works fine in third person view, though. Or in the skel mesh editor. I am pretty sure the problem is not the mesh or apex file, but something with cloth ticking.

So, about the changes: on original ShooterGame, first person arms is atttached to the character, and its position is updated on the function AShooterCharacter::OnCameraUpdate, which is called from AShooterPlayerCameraManager::UpdateCamera.

My changes: I attached the first person arms to the camera instead (Mesh1P->AttachTo(PC->PlayerCameraManager->GetRootComponent());), and don’t do anything on AShooterCharacter::OnCameraUpdate. Well, save for my attempts at calling cloth tick, some posts above.

Edit: I did try to revert to how ShooterGame implemented Mesh1P (attaching to pawn and updating position after UpdateCamera()), but the stretching issue persisted, although it stretched a little less.

I am running 4.2, built from source.

Here are the files I imported into the original ShooterGame. Extract them to Unreal Projects\Shooter Game 4.2\Content\Weapons, and change the Rifle’s blueprint mesh to this one.

ShooterGame’s character is too slow and cloth doesn’t stretches much, but if you look up/down rapidly, you will notice it.

Now, try playing with 2 clients. Get them close to each other and observe how the cloth behaves in third person view. You’ll notice it works fine when it’s not in first person, even during rapid movements.

Also, it stretches even more (in 1st person) when frame rate is slow (play with 3+ clients to decrease framerate and test it).

Hooooray, this was fixed in the latest preview build!

Cloth now ticks if its tick group is set to TG_PostUpdateWork.

I was still getting issues with cloth stretching however, but setting this property (in the mesh that simulates cloth) fixed the problem:

Mesh1P->bLocalSpaceSimulation = true;

I’m not sure if this property is present in 4.2. I’m using the latest 4.3 preview from github.

The cloth on the weapon now looks so awesome!

Thank you so much Epic devs!!

PS - to summarize, the solution was to set the mesh’s tick group Mesh1P->PrimaryComponentTick.TickGroup = TG_PostUpdateWork; (because Mesh1P should update after the camera, as I attached Mesh1P to the camera) and Mesh1P->bLocalSpaceSimulation = true.