SkeletalMesh - Visual Mesh Rotation Precision Issues?

No effect. The aim location is actually determined from the bone rotation of the mesh, so actually the bones / actual transform values are updating fine - but the camera and mesh isn’t. For reference, this is how I get the aim-location in World Space:



FVector UBZGame_UnitComponent::WeaponConvergeLocation() const
{
	const APawn* PawnOwner = Cast<APawn>(GetOwner());
	if (PawnOwner)
	{
		const IBZGame_GameObjectInterface* OwningGO = Cast<IBZGame_GameObjectInterface>(PawnOwner);
		ASSERTV_WR(OwningGO != nullptr, FVector::ZeroVector, TEXT("WeaponConvergeLocation: Invalid GO"));

		const FVector EyepointLocWS = OwningGO->GetRootMesh()->GetSocketLocation(TEXT("HP_Eyepoint"));

		const FVector AimRotation = FRotator(PawnAimOffsets.X, 0.f, 0.f).Vector();
		const FVector AimDir = PawnOwner->GetActorRotation().RotateVector(AimRotation);

		FVector ConvergeLocation = EyepointLocWS + (AimDir * CalcWeaponRange());
		return ConvergeLocation;
	}

	return FVector::ZeroVector;
}


As you can see, the rotation is determined from the rotation of the object mesh - so the transform itself does update, but the camera and all meshes don’t. The ‘Root Mesh’ is the object the rotation is applied to (a USkeletalMeshComponent), The camera and first-person mesh are attached to the root mesh.

I believe the issue is deeper rooted in USceneComponent, possible here in UpdateComponentToWorldWithParent(), but I’m going to have to do further testing to find out.



	// If transform has changed..
	bool bHasChanged;
	{
		//QUICK_SCOPE_CYCLE_COUNTER(STAT_USceneComponent_UpdateComponentToWorldWithParent_HasChanged);
		bHasChanged = !ComponentToWorld.Equals(NewTransform, SMALL_NUMBER);
	}
	if (bHasChanged)
	{
		//QUICK_SCOPE_CYCLE_COUNTER(STAT_USceneComponent_UpdateComponentToWorldWithParent_Changed);
		// Update transform
		ComponentToWorld = NewTransform;
		PropagateTransformUpdate(true, UpdateTransformFlags, Teleport);
	}
	else
	{
		//QUICK_SCOPE_CYCLE_COUNTER(STAT_USceneComponent_UpdateComponentToWorldWithParent_NotChanged);
		PropagateTransformUpdate(false);
	}


It might be that the tolerance (SMALL_NUMBER) causes precision errors when comparing the transforms, I’m not sure. I’ve recently realised that if I move my mouse slowly enough, I can get the reticle to the edge of the screen without getting a single transform update.

Looking into this even further, it appears the PropagateTransformUpdate is responsible for updating the Bounds and Render Transform of the object. I’m assuming this is done because there’s no point re-calculating this for objects that never move (which could be hundreds if not thousands of extra updates and bounds calculations), so this is some form of optimization.

It appears I’ve found a need to have this exposed on a per-scene component basis, so that some objects that may update very minutely can have transform update forced.