Was hoping I wouldn’t have to call for help for this one, but it’s just beyond me.
I modified the ShooterGame so that the camera follows a socket, defined on the mesh (it’s a child of the b_head). It’s working, but when the character moves, there is a sort of offset: the 1st person weapon mesh moves opposite to where the character is going. This happens because the camera is no longer fixed, but follows the mesh’s animation.
So, I realized I had to change the OnCameraUpdate()
function. That function positions the first person mesh when the camera moves.
Here is my code:
void AShooterCharacter::OnCameraUpdate(const FVector& CameraLocation, const FRotator& CameraRotation)
{
USkeletalMeshComponent* DefMesh1P = Cast(GetClass()->GetDefaultSubobjectByName(TEXT("PawnMesh1P")));
const FMatrix DefMeshLS = FRotationTranslationMatrix(DefMesh1P->GetComponentRotation(), CameraLocation + DefMesh1P->RelativeLocation);
const FRotator RotCameraPitch(CameraRotation.Pitch, 0.0f, 0.0f);
const FRotator RotCameraYaw(0.0f, CameraRotation.Yaw, 0.0f);
FMatrix LeveledCameraLS = FRotationTranslationMatrix(RotCameraYaw, CameraLocation);
FMatrix PitchedCameraLS = FRotationMatrix(RotCameraPitch) * LeveledCameraLS;
const FMatrix MeshRelativeToCamera = DefMeshLS * LeveledCameraLS.InverseSafe();
const FMatrix PitchedMesh = MeshRelativeToCamera * PitchedCameraLS;
Mesh1P->SetWorldLocationAndRotation(PitchedMesh.GetOrigin(), PitchedMesh.Rotator());
}
With this code:
- During movement, the weapon looks perfectly still, it only plays the Mesh1P animation (this is the intended behaviour);
- If I aim up/down, the Mesh1P updates correctly.
- But if I look left/right, the Mesh1P doesn’t updates. Its yaw is fixed.
How do I fix the yaw update?
For reference, here’s the original code on ShooterGame. Modified lines are noted with —.
void AShooterCharacter::OnCameraUpdate(const FVector& CameraLocation, const FRotator& CameraRotation)
{
USkeletalMeshComponent* DefMesh1P = Cast(GetClass()->GetDefaultSubobjectByName(TEXT("PawnMesh1P")));
--- const FMatrix DefMeshLS = FRotationTranslationMatrix(DefMesh1P->RelativeRotation, DefMesh1P->RelativeLocation);
const FMatrix LocalToWorld = ActorToWorld().ToMatrixWithScale();
// Mesh rotating code expect uniform scale in LocalToWorld matrix
const FRotator RotCameraPitch(CameraRotation.Pitch, 0.0f, 0.0f);
const FRotator RotCameraYaw(0.0f, CameraRotation.Yaw, 0.0f);
--- const FMatrix LeveledCameraLS = FRotationTranslationMatrix(RotCameraYaw, CameraLocation) * LocalToWorld.InverseSafe();
const FMatrix PitchedCameraLS = FRotationMatrix(RotCameraPitch) * LeveledCameraLS;
const FMatrix MeshRelativeToCamera = DefMeshLS * LeveledCameraLS.InverseSafe();
const FMatrix PitchedMesh = MeshRelativeToCamera * PitchedCameraLS;
--- Mesh1P->SetRelativeLocationAndRotation(PitchedMesh.GetOrigin(), PitchedMesh.Rotator());
}