SpringArm won't update from code!

While converting my player class to C++, I was having trouble implementing a zoom feature which prior to conversion, worked perfectly fine in the Blueprint version. After a little too much trouble, I decided to strip all relevant code out of my player class, and copy/paste the code from the C++ Third Person template. For whatever reason, this did not change anything…

Now here’s the weird part:
If I use the mouse wheel to zoom in/out, then Alt+Tab into the editor with the game running, select my player class from the World Outliner, and take a peek at the SpringArm component, I can see the value of TargetArmLength being updated, but there is no visible change in the actual game. Even stranger than that is when I manually edit the value in the details panel, then it actually does visibly show the changes…
WTF? Why!?

My project’s input settings look like this:
5b4f877a2cec414aa58a9ad7cc93b081.png

And here’s the stripped-down version of my player class:
Player.h


#pragma once

#include "GameFramework/SpringArmComponent.h"
#include "Player.generated.h"

class ABasePlayer;

UCLASS(Config = Game)
class APlayer : public ABasePlayer // NOTE: ABasePlayer is currently an empty class deriving from ACharacter
{
	GENERATED_BODY()

	/* Private Components */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	class USpringArmComponent* CameraBoom;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	class UCameraComponent* FollowCamera;

public:
	/* Class Constructor */
	ATOPAvatarPlayer();

	/* Overrides */
	virtual void SetupPlayerInputComponent(UInputComponent *InInputComponent) override;
	virtual void BeginPlay() override;

	/* Input */
	void Turn(float Value);
	void LookUp(float Value);
	void Zoom(float Value);

	/* Public Class Functions */
	FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
	FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }

	/* Exposed Variables */
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinimumTurnAngle;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MaximumTurnAngle;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinimumLookUpAngle;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MaximumLookUpAngle;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinimumZoom;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MaximumZoom;
};

Player.cpp:



    #include "MyGame.h"
    #include "BasePlayer.h"
    #include "Player.h"
    
    /*
    * Class Constructor
    * =================
    */
    APlayer::APlayer()
    {
    	this->PrimaryActorTick.Target = this;
    	this->PrimaryActorTick.bCanEverTick = true;
    	this->PrimaryActorTick.bStartWithTickEnabled = true;
    
    	GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
    	bUseControllerRotationPitch = true;
    	bUseControllerRotationYaw = true;
    	bUseControllerRotationRoll = false;
    
    	GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...	
    	GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...at this rotation rate
    	GetCharacterMovement()->JumpZVelocity = 600.f;
    	GetCharacterMovement()->AirControl = 0.2f;
    
    	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
    	CameraBoom->AttachTo(RootComponent);
    	CameraBoom->TargetArmLength = 500.0f; // The camera follows at this distance behind the character	
    	CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller
    
    	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
    	FollowCamera->AttachTo(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
    	FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm
    
    	/* Default Class Variables */
    	MinimumTurnAngle = -89.5;
    	MaximumTurnAngle = 89.5;
    	MinimumLookUpAngle = -90.0;
    	MaximumLookUpAngle = -0.15;
    	MinimumZoom = 500.0;
    	MaximumZoom = 1500.0;
    }
    
    /*
    * Input Functions
    * ===============
    */
    void APlayer::Turn(float Value)
    {
    	if (Controller && (Value != 0.0f)) {
    		auto Rotation = Controller->GetControlRotation();
    		auto DesiredAngle = Value + Rotation.Yaw;
    		auto MinAngle = MinimumTurnAngle;
    		auto MaxAngle = MaximumTurnAngle;
    		auto NewYaw = FMath::ClampAngle(DesiredAngle, MinAngle, MaxAngle);
    		auto NewRotation = FRotator::MakeFromEuler(FVector(0.f, Rotation.Pitch, NewYaw));
    		Controller->SetControlRotation(NewRotation);
    		/* Just as expected, this message always displays when I move the mouse horizontally */
    		GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, Controller->GetControlRotation().ToCompactString());
    	}
    }
    
    void APlayer::LookUp(float Value)
    {
    	if (Controller && (Value != 0.0f)) {
    		auto Rotation = Controller->GetControlRotation();
    		auto DesiredAngle = Value + Rotation.Pitch;
    		auto NewPitch = FMath::ClampAngle(DesiredAngle, MinimumLookUpAngle, MaximumLookUpAngle);
    		auto NewRotation = FRotator::MakeFromEuler(FVector(0.f, NewPitch, Rotation.Yaw));
    		Controller->SetControlRotation(NewRotation);
    		/* Just as expected, this message always displays when I move the mouse vertically */
    		GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, Controller->GetControlRotation().ToCompactString());
    	}
    }
    
    void APlayer::Zoom(float Value)
    {
    	auto NewZoom = FMath::Clamp(CameraBoom->TargetArmLength + Value, MinimumZoom, MaximumZoom);
    	if (NewZoom != CameraBoom->TargetArmLength && GEngine) {
    		CameraBoom->TargetArmLength = NewZoom;
    		/* Just as expected, this message always displays when I use the mouse wheel */
    		GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, FString::FromInt(CameraBoom->TargetArmLength));
    	}
    }
    
    /*
    * Overrided Functions
    * ===================
    */
    void APlayer::SetupPlayerInputComponent(UInputComponent *InInputComponent)
    {
    	this->InputComponent->BindAxis("Turn", this, &APlayer::Turn);
    	this->InputComponent->BindAxis("LookUp", this, &APlayer::LookUp);
    	this->InputComponent->BindAxis("Zoom", this, &APlayer::Zoom);
    }
    
    void APlayer::BeginPlay()
    {
    	/* Dirty hack to get the Tick function to work in this class */
    	auto level = GetWorld()->GetLevel(0);
    	this->PrimaryActorTick.RegisterTickFunction(level);
    }