Download

Input Axis Not Working for a Camera - Clean Template/4.7.6

Hi mates.

Started coding tutorials. Made an empty template. Followed Cbrew’s great tutorial (here) Made Input Actions and Axis. Set my pawn as the default one.

Somehow mouse zooming in and out working but not the WASD. Is there an inherent bug with the clean template or somethiing ? Spent 3 days and I am simply too tired. If you mates Have any idea please help me.

Header file (RTSCamera.h)


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

#pragma once

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

/** AFESpectatorPawn
* This Pawn Will Move Like An RTS Camera
*/

UCLASS()
class RTS_API ARTSCamera : public APawn
{
	GENERATED_BODY()

	ARTSCamera(const FObjectInitializer& ObjectInitializer);

public:


	/** Camera Component */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera)
	UCameraComponent* CameraComponent;

	/** Camera Z Angle */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	float CameraZAnlge;

	/** Camera Radius From Pawn Position */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	float CameraRadius;

	/** Camera Height Angle */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	float CameraHeightAngle;

	/** Camera Zoom Speed */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	float CameraZoomSpeed;

	/** Camera Radius Max */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	float CameraRadiusMax;

	/** Camera Radius Min */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	float CameraRadiusMin;

	/** Camera Movement Speed */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	float CameraMovementSpeed;

	/** Camera Scroll Boundary */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	float CameraScrollBoundary;

	/** Should the camera move? */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
	bool bCanMoveCamera;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Camera)
	bool bAddDefaultMovementBindings;

private:
	/** Sets up player inputs
	*    @param InputComponent - Input Component
	*/
	void SetupPlayerInputComponent(class UInputComponent* InputComponent);


public:

	UFUNCTION()
	void BeginPlay();


	/** Zooms In The Camera */
	UFUNCTION()
	void ZoomIn();

	/** Zooms Out The Camera */
	UFUNCTION()
	void ZoomOut();

	/** Gets the roatation of the camera with only the yaw value
	* @return - returns a rotator that is (0, yaw, 0) of the Camera
	*/
	UFUNCTION()
	FRotator GetIsolatedCameraYaw();

	/** Moves the camera forward
	* @param direcation - (1.0 for forward, -1.0 for backward)
	*/
	UFUNCTION()
	void MoveCameraForward(float direction);

	/** Moves the camera forward
	* @param direcation - (1.0 for right, -1.0 for left)
	*/
	UFUNCTION()
	void MoveCameraRight(float direction);

	/** Repositions The Camera */
	UFUNCTION()
	void RepositionCamera();

	/** Tick Function, Called Every Frame */
	UFUNCTION()
	virtual void Tick(float DeltaSeconds) OVERRIDE;
	
	
};


Source file (RTSCamera.cpp)


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

#include "RTS.h"
#include "RTSCamera.h"


// Sets default values
ARTSCamera::ARTSCamera(const class FObjectInitializer& PCIP)


{
	//Disable Standard WASD Movement
	bAddDefaultMovementBindings = false;

	//Set Default Camera Values
	CameraRadius = 1000.0f;
	CameraZAnlge = 0.0f;
	CameraHeightAngle = 70.0f;
	CameraZoomSpeed = 32.0f;
	CameraRadiusMin = 750.0f;
	CameraRadiusMax = 2000.0f;
	CameraMovementSpeed = 2000.0f;
	CameraScrollBoundary = 25.0f;
	//TODO: While selecting units, the camera CANNOT move!
	bCanMoveCamera = true;

	//Intialize The Camera
	CameraComponent = PCIP.CreateDefaultSubobject<UCameraComponent>(this, TEXT("RTS Camera"));
	CameraComponent->AttachParent = this->GetRootComponent();
	CameraComponent->bUsePawnControlRotation = false;
	RepositionCamera();

	//Enable Tick function
	PrimaryActorTick.bCanEverTick = true;



}

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

// Called every frame

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

	//Bind Mouse Wheel Zooming Actions
	InputComponent->BindAction("WheelMouseUp", IE_Pressed, this, &ARTSCamera::ZoomIn);
	InputComponent->BindAction("WheelMouseDown", IE_Pressed, this, &ARTSCamera::ZoomOut);

	//Bind WASD Movement
	//FOR TESTING PURPOSES ONLY!!!
	InputComponent->BindAxis("MoveForward", this, &ARTSCamera::MoveCameraForward);
	InputComponent->BindAxis("MoveRight", this, &ARTSCamera::MoveCameraRight);

}

void ARTSCamera::ZoomIn()
{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
	return;

	//Decrease the CameraRadius but clamp it between the min and max radii
	CameraRadius = FMath::Clamp(CameraRadius - CameraZoomSpeed, CameraRadiusMin, CameraRadiusMax);

	//Reposition the camera in the local space
	RepositionCamera();
}

void ARTSCamera::ZoomOut()
{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
	return;

	//Increase the CameraRadius but clamp it between the min and max radii
	CameraRadius = FMath::Clamp(CameraRadius + CameraZoomSpeed, CameraRadiusMin, CameraRadiusMax);

	//Reposition the camera in the local space
	RepositionCamera();
}

FRotator ARTSCamera::GetIsolatedCameraYaw()
{
	//Return a FRotator containing (0, CameraYaw, 0)
	return FRotator(0.0f, CameraComponent->ComponentToWorld.Rotator().Yaw, 0.0f);
}






void ARTSCamera::MoveCameraForward(float direction)

{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
	return;

	//Calculate how much to move the camera by
	float movementValue = direction * CameraMovementSpeed;

	//Create a delta vector that moves by the movementValue in the direction of the camera's yaw
	FVector deltaMovement = movementValue * GetIsolatedCameraYaw().Vector();

	//Add the delta to a new vector
	FVector newLocation = this->GetActorLocation() + deltaMovement;

	//Set the new location of the pawn
	SetActorLocation(newLocation);
}





void ARTSCamera::MoveCameraRight(float direction)
{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
	return;

	//Calculate how much to move the camera by
	float movementValue = direction * CameraMovementSpeed;

	//Create a delta vector that moves by the movementValue in the direction of the right of the camera's yaw
	FVector deltaMovement = movementValue * (FRotator(0.0f, 90.0f, 0.0f) + GetIsolatedCameraYaw()).Vector();

	//Add the delta to a new vector
	FVector newLocation = this->GetActorLocation() + deltaMovement;

	//Set the new location of the pawn
	SetActorLocation(newLocation);
}

void ARTSCamera::RepositionCamera()
{
	//Create variables to hold the new values
	FVector newLocation(0.0f, 0.0f, 0.0f);
	FRotator newRotation(0.0f, 0.0f, 0.0f);

	//Find Cos and Sin of the Camera Z Angle
	float sinCameraZAngle = FMath::Sin(FMath::DegreesToRadians(CameraZAnlge));
	float cosCameraZAngle = FMath::Cos(FMath::DegreesToRadians(CameraZAnlge));

	//Find the Cos and Sin of the Camera Height Angle
	float sinCameraHeightAngle = FMath::Sin(FMath::DegreesToRadians(CameraHeightAngle));
	float cosCameraHeightAngle = FMath::Cos(FMath::DegreesToRadians(CameraHeightAngle));

	//Set newLocation X to cosCameraZAngle * sinCameraHeightAngle * CameraRadius
	newLocation.X = cosCameraZAngle * cosCameraHeightAngle * CameraRadius;

	//Set newLocation Y to sinCameraZangle * sinCameraHeightAngle * CameraRadius
	newLocation.Y = sinCameraZAngle * cosCameraHeightAngle * CameraRadius;

	//Set newLocation Z to cosCameraHeightAngle * CameraRadius
	newLocation.Z = sinCameraHeightAngle * CameraRadius;

	//Set the new rotations
	newRotation = (FVector(0.0f, 0.0f, 0.0f) - newLocation).Rotation();


	//Set the camera's location and rotation to the new values
	CameraComponent->SetRelativeLocation(newLocation);
	CameraComponent->SetRelativeRotation(newRotation);
}



void ARTSCamera::Tick(float DeltaSeconds)
{

	Super::Tick(DeltaSeconds);

	//Create variables to hold mouse position and screen size
	FVector2D mousePosition;
	FVector2D viewportSize;

	//Get mouse position and screen size
	UGameViewportClient* gameViewport = GEngine->GameViewport;

	//Make sure viewport exists
	check(gameViewport);
	gameViewport->GetViewportSize(viewportSize);

	//Make sure the viewport has focus(contains the mouse)
	if (gameViewport->IsFocused(gameViewport->Viewport) && gameViewport->GetMousePosition(mousePosition) && bCanMoveCamera)
	{
		//Check if the mouse is at the left or right edge of the screen and move accordingly
		if (mousePosition.X < CameraScrollBoundary)
		{
			MoveCameraRight(-1.0f * DeltaSeconds);
		}
		else if (viewportSize.X - mousePosition.X < CameraScrollBoundary)
		{
			MoveCameraRight(1.0f * DeltaSeconds);
		}

		//Check if the mouse is at the top or bottom edge of the screen and move accordingly
		if (mousePosition.Y < CameraScrollBoundary)
		{
			MoveCameraForward(1.0f * DeltaSeconds);
		}
		else if (viewportSize.Y - mousePosition.Y < CameraScrollBoundary)
		{
			MoveCameraForward(-1.0f * DeltaSeconds);
		}
	}


}


My Input Settings.

zlTlJrql.jpg

Thanks beforehand.

Am I alone in here ? :slight_smile:

I made a RTS camera system using blueprints.
I can make out some of the code stuff but one thing i cant make it is what exactly it is.

For my Camera system i used an character blueprint. This allowed me to set the collisions to ignore everything except a custom floor collision box, so it floats on that.
Then WASD worked fine as it would use the character movement component to move.

When i used spectator pawns as my base class my WASD would not work and i simply couldn’t afford to spend much time figuring out why not and thats why i ended up using a character as the base class.

Hopefully just by reading this it triggers something you havent thought of yet.

Good luck

Nie insgiht. So character worked instead of pawn eh ? This might be the reason. Since Blueprints are basically small C++ files interpreted by the system this might work. I will try something and come back.

Thanks mate.

Hey mate !

I created a character (RTSCharacter) in C++ simply using the same code and then changing the default pawn to that one in game mode. WASD still doesn’t work but for some reason now mouse can pan the camera when it is near the screen, a future that didn’t work before ?

LOL :smiley:

I don’t even :smiley:

Let me tinker with it a bit more I have the feeling I can do this :smiley: (Even more LOL :smiley: ) and I will write it here.

Crocopede Thanks mate you were right. I made a new character class and used this instead and it worked. Thanks a ton !

In fact as it turns out it is a known bug. Here:

https://answers.unrealengine.com/questions/154489/why-i-cant-move-pawn-but-only-character.html

https://answers.unrealengine.com/questions/214612/475-gamemode-always-reset-default-pawn-class.html

The only thing is since it is a caharcter when you press Play button you fall from sky a bit and when you hit ground (or somethnig else) it works as you wish.

So to anyone who is having problems with pawns for cameras. Here is the solution:

Create Character -> RTSCharacter

** RTSCharacter.h**


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

#pragma once

#include "GameFramework/Character.h"
#include "RTSCharacter.generated.h"

UCLASS()
class RTS_API ARTSCharacter : public ACharacter
{
	GENERATED_BODY()

	ARTSCharacter(const FObjectInitializer& ObjectInitializer);

public:


	/** Camera Component */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera)
		UCameraComponent* CameraComponent;

	/** Camera Z Angle */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		float CameraZAnlge;

	/** Camera Radius From Pawn Position */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		float CameraRadius;

	/** Camera Height Angle */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		float CameraHeightAngle;

	/** Camera Zoom Speed */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		float CameraZoomSpeed;

	/** Camera Radius Max */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		float CameraRadiusMax;

	/** Camera Radius Min */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		float CameraRadiusMin;

	/** Camera Movement Speed */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		float CameraMovementSpeed;

	/** Camera Scroll Boundary */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		float CameraScrollBoundary;

	/** Should the camera move? */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
		bool bCanMoveCamera;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Camera)
		bool bAddDefaultMovementBindings;




private:
	/** Sets up player inputs
	*    @param InputComponent - Input Component
	*/
	void SetupPlayerInputComponent(class UInputComponent* InputComponent);


public:


	// Sets default values for this character's properties
	ARTSCharacter();

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

	
	/** Zooms In The Camera */
	UFUNCTION()
		void ZoomIn();

	/** Zooms Out The Camera */
	UFUNCTION()
		void ZoomOut();

	/** Gets the roatation of the camera with only the yaw value
	* @return - returns a rotator that is (0, yaw, 0) of the Camera
	*/
	UFUNCTION()
		FRotator GetIsolatedCameraYaw();

	/** Moves the camera forward
	* @param direcation - (1.0 for forward, -1.0 for backward)
	*/
	UFUNCTION()
	void MoveCameraForward(float direction);

	UFUNCTION()
	void MoveCameraBackward(float direction);

	UFUNCTION()
	void MoveCameraLeft(float direction);

	/** Moves the camera forward
	* @param direcation - (1.0 for right, -1.0 for left)
	*/
	UFUNCTION()
		void MoveCameraRight(float direction);

	/** Repositions The Camera */
	UFUNCTION()
		void RepositionCamera();


	
};


** RTSChracter.cpp**


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

#include "RTS.h"
#include "RTSCharacter.h"


// Sets default values
ARTSCharacter::ARTSCharacter(const class FObjectInitializer& PCIP)
{
	//Disable Standard WASD Movement
	bAddDefaultMovementBindings = false;

	//Set Default Camera Values
	CameraRadius = 1000.0f;
	CameraZAnlge = 0.0f;
	CameraHeightAngle = 70.0f;
	CameraZoomSpeed = 32.0f;
	CameraRadiusMin = 750.0f;
	CameraRadiusMax = 2000.0f;
	CameraMovementSpeed = 20.0f;
	CameraScrollBoundary = 25.0f;
	//TODO: While selecting units, the camera CANNOT move!
	bCanMoveCamera = true;

	//Intialize The Camera
	CameraComponent = PCIP.CreateDefaultSubobject<UCameraComponent>(this, TEXT("RTS Camera"));
	CameraComponent->AttachParent = this->GetRootComponent();
	CameraComponent->bUsePawnControlRotation = false;
	RepositionCamera();



 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

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

// Called every frame
void ARTSCharacter::Tick( float DeltaSeconds )
{
	Super::Tick( DeltaSeconds );

	//Create variables to hold mouse position and screen size
	FVector2D mousePosition;
	FVector2D viewportSize;

	//Get mouse position and screen size
	UGameViewportClient* gameViewport = GEngine->GameViewport;

	//Make sure viewport exists
	check(gameViewport);
	gameViewport->GetViewportSize(viewportSize);

	//Make sure the viewport has focus(contains the mouse)
	if (gameViewport->IsFocused(gameViewport->Viewport) && gameViewport->GetMousePosition(mousePosition) && bCanMoveCamera)
	{
		//Check if the mouse is at the left or right edge of the screen and move accordingly
		if (mousePosition.X < CameraScrollBoundary)
		{
			MoveCameraRight(-50.0f * DeltaSeconds);
		}
		else if (viewportSize.X - mousePosition.X < CameraScrollBoundary)
		{
			MoveCameraRight(50.0f * DeltaSeconds);
		}

		//Check if the mouse is at the top or bottom edge of the screen and move accordingly
		if (mousePosition.Y < CameraScrollBoundary)
		{
			MoveCameraForward(50.0f * DeltaSeconds);
		}
		else if (viewportSize.Y - mousePosition.Y < CameraScrollBoundary)
		{
			MoveCameraForward(-50.0f * DeltaSeconds);
		}
	}


}

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


	check(InputComponent);

	//Bind Mouse Wheel Zooming Actions
	InputComponent->BindAction("WheelMouseUp", IE_Pressed, this, &ARTSCharacter::ZoomIn);
	InputComponent->BindAction("WheelMouseDown", IE_Pressed, this, &ARTSCharacter::ZoomOut);

	//Bind WASD Movement
	//FOR TESTING PURPOSES ONLY!!!
	InputComponent->BindAxis("MoveForward", this, &ARTSCharacter::MoveCameraForward);
	InputComponent->BindAxis("MoveBackward", this, &ARTSCharacter::MoveCameraBackward);
	InputComponent->BindAxis("MoveRight", this, &ARTSCharacter::MoveCameraRight);
	InputComponent->BindAxis("MoveLeft", this, &ARTSCharacter::MoveCameraLeft);

}

void ARTSCharacter::ZoomIn()
{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
		return;

	//Decrease the CameraRadius but clamp it between the min and max radii
	CameraRadius = FMath::Clamp(CameraRadius - CameraZoomSpeed, CameraRadiusMin, CameraRadiusMax);

	//Reposition the camera in the local space
	RepositionCamera();
}

void ARTSCharacter::ZoomOut()
{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
		return;

	//Increase the CameraRadius but clamp it between the min and max radii
	CameraRadius = FMath::Clamp(CameraRadius + CameraZoomSpeed, CameraRadiusMin, CameraRadiusMax);

	//Reposition the camera in the local space
	RepositionCamera();
}

FRotator ARTSCharacter::GetIsolatedCameraYaw()
{
	//Return a FRotator containing (0, CameraYaw, 0)
	return FRotator(0.0f, CameraComponent->ComponentToWorld.Rotator().Yaw, 0.0f);
}






void ARTSCharacter::MoveCameraForward(float direction)

{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
		return;

	//Calculate how much to move the camera by
	float movementValue = direction * CameraMovementSpeed;

	//Create a delta vector that moves by the movementValue in the direction of the camera's yaw
	FVector deltaMovement = movementValue * GetIsolatedCameraYaw().Vector();

	//Add the delta to a new vector
	FVector newLocation = this->GetActorLocation() + deltaMovement;

	//Set the new location of the pawn
	SetActorLocation(newLocation);
}




void ARTSCharacter::MoveCameraBackward(float direction)

{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
		return;

	//Calculate how much to move the camera by
	float movementValue = direction * CameraMovementSpeed;

	//Create a delta vector that moves by the movementValue in the direction of the camera's yaw
	FVector deltaMovement = movementValue * GetIsolatedCameraYaw().Vector();

	//Add the delta to a new vector
	FVector newLocation = this->GetActorLocation() - deltaMovement;

	//Set the new location of the pawn
	SetActorLocation(newLocation);
}





void ARTSCharacter::MoveCameraRight(float direction)
{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
		return;

	//Calculate how much to move the camera by
	float movementValue = direction * CameraMovementSpeed;

	//Create a delta vector that moves by the movementValue in the direction of the right of the camera's yaw
	FVector deltaMovement = movementValue * (FRotator(0.0f, 90.0f, 0.0f) + GetIsolatedCameraYaw()).Vector();

	//Add the delta to a new vector
	FVector newLocation = this->GetActorLocation() + deltaMovement;

	//Set the new location of the pawn
	SetActorLocation(newLocation);
}




void ARTSCharacter::MoveCameraLeft(float direction)
{
	//Don't execute any further if the camera can't move
	if (!bCanMoveCamera)
		return;

	//Calculate how much to move the camera by
	float movementValue = direction * CameraMovementSpeed;

	//Create a delta vector that moves by the movementValue in the direction of the right of the camera's yaw
	FVector deltaMovement = movementValue * (FRotator(0.0f, 90.0f, 0.0f) + GetIsolatedCameraYaw()).Vector();

	//Add the delta to a new vector
	FVector newLocation = this->GetActorLocation() - deltaMovement;

	//Set the new location of the pawn
	SetActorLocation(newLocation);
}



void ARTSCharacter::RepositionCamera()
{
	//Create variables to hold the new values
	FVector newLocation(0.0f, 0.0f, 0.0f);
	FRotator newRotation(0.0f, 0.0f, 0.0f);

	//Find Cos and Sin of the Camera Z Angle
	float sinCameraZAngle = FMath::Sin(FMath::DegreesToRadians(CameraZAnlge));
	float cosCameraZAngle = FMath::Cos(FMath::DegreesToRadians(CameraZAnlge));

	//Find the Cos and Sin of the Camera Height Angle
	float sinCameraHeightAngle = FMath::Sin(FMath::DegreesToRadians(CameraHeightAngle));
	float cosCameraHeightAngle = FMath::Cos(FMath::DegreesToRadians(CameraHeightAngle));

	//Set newLocation X to cosCameraZAngle * sinCameraHeightAngle * CameraRadius
	newLocation.X = cosCameraZAngle * cosCameraHeightAngle * CameraRadius;

	//Set newLocation Y to sinCameraZangle * sinCameraHeightAngle * CameraRadius
	newLocation.Y = sinCameraZAngle * cosCameraHeightAngle * CameraRadius;

	//Set newLocation Z to cosCameraHeightAngle * CameraRadius
	newLocation.Z = sinCameraHeightAngle * CameraRadius;

	//Set the new rotations
	newRotation = (FVector(0.0f, 0.0f, 0.0f) - newLocation).Rotation();


	//Set the camera's location and rotation to the new values
	CameraComponent->SetRelativeLocation(newLocation);
	CameraComponent->SetRelativeRotation(newRotation);
}


Go to Level Blueprints-> Edit Game Mode “Name”

Change Default Pawn to RTSCharacter.

Enjoy :smiley:

I’ll talk with CBrew to update the tutorials if he is OK with it. And I’ll try to add Camera Rotation and Left Click Panning then also add it to tutorials.

Man that really took some time to figure it out. I had switched to UE4 expecting to find these kind of things to be easier in C++ :smiley: . Well whatever.