I have a Targeting system. I am able to acquire the target, and cycle through them, but the camera rotation is off, jerky and stutters.
right now it is a 3rd person Camera is on a SpringArm and I have it set and a raised angle to give the player more of the scene and less of the player model
void AMyCharacter::Tick(float DeltaTime){
if ( bTargetLocked )
{
if ( LockOnTarget != nullptr )
{
// FVector Start = FollowCamera->GetComponentLocation();
FVector Start = GetActorLocation();
// "for the purpose of this question it is just a UActorComponent that will have widgets but that is later"
FVector Target = LockOnTarget->GetOwner()->GetActorLocation();
FRotator DesiredRotation = UKismetMathLibrary::FindLookAtRotation(Start, Target);
FollowCamera->SetWorldRotation(FQuat(DesiredRotation));
}
else
{
FVector Target = (GetActorLocation() - FollowCamera->GetComponentLocation());
FollowCamera->SetWorldRotation(FQuat(Target.Rotation()));
bTargetLocked = false;
}
}
}
right now the LockOnTarget becomes the focus and it tracks the target, but the camera just snaps, the Character can deviate from the middle of the screen (to the point where the character can just leave the frame.
I am not concerned with the player shifting the camera with keyboard/gamepad/mouse as I am using that function for target cycling so Look is no longer modifying the camera directly if (bTargetLocked == true)
ended up struggling with this a bit, but ended up with this
void AMyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// should probably be a class variable to for EditAnywhere
float CamSpeed = 100.0f;
// Try to orient the camera in the direction toward the current targets Location
if ( bTargetLock )
{
// for the purpose of this think of it as a UActorComponent that holds Square distance to player.
if ( LockOnTarget != nullptr )
{
FVector Start = FollowCamera->GetComponentLocation();
FVector End = LockOnTarget->GetOwner()->GetActorLocation();
FHitResult HitResult;
FCollisionQueryParams Params;
Params.AddIgnoredActor(this);
if( !GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility, Params) && (LockOnTarget->SqrDist < GetMaxDistSqr()))
{
FRotator DRotation = UKismetMathLibrary::FindLookAtRotation(Start, End);
FRotator CRotation = CameraBoom->GetComponentRotation();
DRotation = FRotator(DRotation.Pitch, DRotation.Yaw, CRotation.Roll);
// consistent, jerky but consistent
// CameraBoom->SetWorldRotation(DRotation);
// less consistent, but smoother (could be even smoother with unconstrained tick)
CameraBoom->SetWorldRotation(FMath::RInterpTo(CRotation, DRotation, DeltaTime, CamSpeed));
DRotation = UKismetMathLibrary::FindLookAtRotation(Start, End);
FollowCamera->SetWorldRotation(FMath::RInterpTo(FollowCamera->GetComponentRotation(), DRotation, DeltaTime, CamSpeed));
}
else
{
bTargetLock = false;
LockOnTarget = nullptr;
}
}
else
{
bTargetLock = false;
}
// could add delay logic to make target cycling smoother
}
// this becomes false when target lock is acquired
else if(CameraBoom->bUsePawnControlRotation == false )
{
// float CamSpeed = 100.0f;
CameraBoom->SetWorldRotation(FMath::RInterpConstantTo(CameraBoom->GetComponentRotation(), GetControlRotation(), DeltaTime, CamSpeed));
FRotator DRotation = UKismetMathLibrary::FindLookAtRotation(FollowCamera->GetComponentLocation(), GetActorLocation());
FollowCamera->SetWorldRotation(FMath::RInterpConstantTo(FollowCamera->GetComponentRotation(), DRotation, DeltaTime, CamSpeed));
// Why does this function not exist 'NearlyZero() exists but not NearlyEqual() Really'
if ( UFLibMath::RotatorNearlyEqual(GetControlRotation(), CameraBoom->GetComponentRotation()) )
{
CameraBoom->bUsePawnControlRotation = true;
}
}
}
it gives a semi-fluid targeting system that still allows the player character to move freely while the target is locked On.
for future readers I will leave the implementation of acquiring the target lock in the first place, or cycling through them to your implementation.