Help with C++ (rts) Camera

Hi,

I am trying to create a RTS camera. I followed some tutorial online, but they are all in bp (this works), so I am trying to convert one to C++ since I prefer using that since I know that already. The goal is to have a camera that can rotate/move/zoom etc. Well I my camera is on top of a pawn, which I am moving with my PlayerController class. The pawn code looks like this:

CameraPawn.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Pawn.h"
#include "CameraPawn.generated.h"

UCLASS()
class RTSC_API ACameraPawn : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	ACameraPawn();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;

	USpringArmComponent* GetSpringArm();

protected:
	UPROPERTY(EditAnywhere)
	USpringArmComponent* m_CameraSpringArm;
	UCameraComponent* m_Camera;
	
};

CameraPawn.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "RTSC.h"
#include "CameraPawn.h"


// Sets default values
ACameraPawn::ACameraPawn()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
	m_CameraSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm"));
	m_CameraSpringArm->SetupAttachment(RootComponent);
	m_CameraSpringArm->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, 50.0f), FRotator(-60.0f, 0.0f, 0.0f));
	m_CameraSpringArm->TargetArmLength = 1500.f;
	m_CameraSpringArm->bEnableCameraLag = true;
	m_CameraSpringArm->CameraLagSpeed = 3.0f;

	m_Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("GameCamera"));
	m_Camera->SetupAttachment(m_CameraSpringArm, USpringArmComponent::SocketName);

	UGameplayStatics::GetPlayerController(this, 0);
}

// Called when the game starts or when spawned
void ACameraPawn::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ACameraPawn::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

}

// Called to bind functionality to input
void ACameraPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	Super::SetupPlayerInputComponent(InputComponent);

}

USpringArmComponent* ACameraPawn::GetSpringArm()
{
	if (m_CameraSpringArm != 0)
		return m_CameraSpringArm;
	else
		return 0;
}

Lots of the code is copy pasted and it looks okay to me.

Now where my problem is this: In the controller before I implented rorating and stuff, I was just changing the pawn’s location. Well that did not work anymore when I started rorating, so I thought about using the transform functions. But I can’t get my head around it how it 100% works. So this is my code at the moment:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/PlayerController.h"
#include "CameraPawnController.generated.h"

/**
 * 
 */
class ACameraPawn;
UCLASS()
class RTSC_API ACameraPawnController : public APlayerController
{
	GENERATED_BODY()

public:
	ACameraPawnController();

	virtual void SetupInputComponent() override;
	virtual void Tick(float DeltaSeconds) override;

protected:


private:
	ACameraPawn* m_CameraPawn;
	
	FVector2D MovementInput;
	FVector2D CameraInput;

	bool m_ZoomingIn;
	bool m_ZoomingOut;

	bool m_Panning;

	void MoveForward(float AxisValue);
	void MoveRight(float AxisValue);
	void Pancamera();
	void stop();
	void ZoomIn();
	void ZoomOut();
};

.cpp file

// Fill out your copyright notice in the Description page of Project Settings.

#include "RTSC.h"
#include "CameraPawnController.h"
#include "CameraPawn.h"

ACameraPawnController::ACameraPawnController()
{
	bShowMouseCursor = true;

	m_ZoomingIn = false;
	m_ZoomingOut = false;
	m_Panning = false;
}

void ACameraPawnController::SetupInputComponent() 
{
	Super::SetupInputComponent();

	InputComponent->BindAxis("MoveForward", this, &ACameraPawnController::MoveForward);
	InputComponent->BindAxis("MoveRight", this, &ACameraPawnController::MoveRight);

	InputComponent->BindAction("ZoomIn" , IE_Pressed, this, &ACameraPawnController::ZoomIn);
	InputComponent->BindAction("ZoomOut", IE_Pressed, this, &ACameraPawnController::ZoomOut);

	InputComponent->BindAction("Pan", IE_Pressed, this, &ACameraPawnController::Pancamera);
	InputComponent->BindAction("Pan", IE_Released, this, &ACameraPawnController::stop);
}

void ACameraPawnController::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	if (!MovementInput.IsZero())
	{
		MovementInput = MovementInput.GetSafeNormal() * 1300.0f;
		FVector NewLocation = GetPawn()->GetActorLocation();
		
		NewLocation += GetActorForwardVector() * MovementInput.X * DeltaSeconds;
		NewLocation += GetActorRightVector() * MovementInput.Y * DeltaSeconds;
		//GetPawn()->SetActorLocation(NewLocation);
		

		FVector NewLocation = GetPawn()->GetActorLocation();
		FTransform NewTransform = GetPawn()->GetActorTransform();
		NewTransform.SetLocation = NewLocation;
		GetPawn()->SetActorTransform(NewTransform);
	}

	if (m_ZoomingIn)
	{
		m_ZoomingIn = false;

		ACameraPawn* camera = dynamic_cast<ACameraPawn*>(GetPawn());

		if(camera->GetSpringArm()->TargetArmLength > 500)
			camera->GetSpringArm()->TargetArmLength -= 110;
	}

	if (m_ZoomingOut)
	{
		m_ZoomingOut = false;

		ACameraPawn* camera = dynamic_cast<ACameraPawn*>(GetPawn());

		if(camera->GetSpringArm()->TargetArmLength < 3000)
		 camera->GetSpringArm()->TargetArmLength += 110;
	}

	if (m_Panning)
	{
		float x, y;
		GetInputMouseDelta(x, y);
		FRotator NewRotator = GetPawn()->GetActorRotation();
		NewRotator.Yaw += x;
		NewRotator.Pitch += y;

		NewRotator.Pitch = FMath::Clamp<float>(NewRotator.Pitch, -150, 75);

		GetPawn()->SetActorRelativeRotation(NewRotator);


		
	}

}

void ACameraPawnController::MoveForward(float AxisValue)
{
	MovementInput.X = FMath::Clamp<float>(AxisValue, -1.0f, 1.0f);
}

void  ACameraPawnController::MoveRight(float AxisValue)
{
	MovementInput.Y = FMath::Clamp<float>(AxisValue, -1.0f, 1.0f);
}

void ACameraPawnController::Pancamera()
{
	m_Panning = true;
}

void ACameraPawnController::stop()
{
	m_Panning = false;
}

void ACameraPawnController::ZoomIn()
{
	m_ZoomingIn = true;
}

void ACameraPawnController::ZoomOut()
{
	m_ZoomingOut = true;
}

I know the zoomint/out restriciotn does not work 100% and that I should make all the variables public for bleuprints, but this is currently just to make it work. Maybe Im using the wrong approach here, but if some could give me advice on anything on the code, please do so :slight_smile:

Thanks :slight_smile: