I am coding a camera system for my platformer and this was one issue I had to tackle - the camera would need to be “free” (almost default behavior), fixed to a relative point or fixed to an absolute position. The code seen below happens in my actor’s Tick function:
FMinimalViewInfo cameraInfo; CalcCamera(DeltaTime, cameraInfo); //Dummy location for testing. This is only fixed along the X axis, the other two behave as they would normally. FVector IntendedPosition = FVector(-1200, cameraInfo.Location.Y, cameraInfo.Location.Z); FVector Direction = cameraInfo.Location - IntendedPosition; float IntendedArmLength = Direction.Size(); Direction.Normalize(); FRotator rotation = Direction.Rotation(); rotation.Normalize(); FRotator newRotation = FMath::Lerp(GetControlRotation(), rotation, DeltaTime); newRotation.Normalize(); GetController()->SetControlRotation(newRotation); CameraBoom->TargetArmLength = FMath::Lerp(CameraBoom->TargetArmLength, FVector::Dist(IntendedPosition, cameraInfo.Location), DeltaTime);
Basically what I do is this - take the difference between my intended position and my current camera position, make an FRotator out of that and lerp the rotation of my controller to it. Then I take the distance between the two mentioned points and lerp to that as the target arm length of my camera boom. Note that, since both lerps use just DeltaTime in the code above, the adjustment is laggy and gradual… One can add a multiplier to make it tighter. This behavior has its hickups (when the player is really close to the locked position for example) but it serves well when I need to switch my 3D platformer into a 2.5D platformer in a certain section.