Camera follow multiple Pawns.

Hello!

I’m working on replicating the camera from these games (one, two, three). The idea that I get from observing those games, is that it gets the middle vector between all player(s), then uses that to place the camera and orient around it. Below is my current code for achieving this, but I’m stumped on how I should go about making it include the players themselves. One of the ideas I had is that I change the target arm length based off the middle vector, but it didn’t produce desired results as you can see in the pictures.

Would love any tips/guidance on the best way to go about this. Thanks!


void AWSDK_AdminCamera::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	OrientateCamera();

	CameraBoom->TargetArmLength = FindRequiredSize();
}

void AWSDK_AdminCamera::OrientateCamera()
{
	FindAveragePosition();

	SetActorLocation(m_DesiredPosition);

	DrawDebugSphere(GetWorld(), m_DesiredPosition, 26, 16, FColor(255, 0, 0), false, 2.0f, 0);
}


void AWSDK_AdminCamera::FindAveragePosition()
{
	FVector averagePos = FVector(0, 0, 0);
	for (int i = 0; i < PawnTable.Num(); i++)
	{
		if (PawnTable* != nullptr)
		{
			averagePos += PawnTable*->GetActorLocation();
		}
	}

	if (PawnTable.Num() > 0)
		averagePos /= PawnTable.Num();

	m_DesiredPosition = averagePos;
}

float AWSDK_AdminCamera::FindRequiredSize()
{
	float size = 0.0f;
	for (int j = 0; j < PawnTable.Num(); j++)
	{
		if (PawnTable[j] != nullptr)
		{
			size = FMath::Max(size, FMath::Abs(m_DesiredPosition.Y));
			size = FMath::Max(size, FMath::Abs(m_DesiredPosition.X));
		}
	}

	size += 5.0f;
	size = FMath::Max(size, 400.0f);

	return size;
}

Results:

Just a thought here, not sure how sound the math would be:

  • Find the distance between the two actors
  • Make the middle that vector your middle vector
  • Based on how far away the characters are from each other, use an offset to increase or decrease the arms length on the camera.

Then use a clamp to determine how far the camera can go in any direction.

That’s what the above code does.