Hi there,
Following various tutorials, I created camera control for a player character through blueprint. Now I’m trying to implement this through C++, but not finding the same success.
Character components in the blueprint method were:
- RootComponent
- SceneComponent (Axis Input → AddLocalRotation[Yaw])
- SpringArm (Axis Input → AddLocalRotation[Pitch])
- Camera
In this setup, the player could walk around, and the camera moved with the character.
But now that I have replicated the creation of these components through C++ instead of in blueprint, the camera no longer moves with the player character.
I have made the following observations:
- Nothing displays in the Details pane for the now-inherited components above (Capsule and Mesh do show details, I didn’t touch those in C++)
- I can use the inherited SceneComponent (PlayerCameraGimbalComponent) in Blueprint, by dragging the reference into a graph
- I cannot use the SpringArm or Camera in an event graph
- When Playing the game, the player camera view starts in the correct position, as defined in my C++, but doesn’t move with the character, or rotate from axis input
Been banging on this for a long time now… if someone can provide insight, it would be much appreciated!
Character setup from C++, also showing no Details:
282920-
Cannot use C++ components as blueprint references:
Input:
Header:
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Player Cam Control")
USceneComponent* PlayerCameraGimbalComponent;
USpringArmComponent* PlayerCameraSpringArmComponent;
UCameraComponent* PlayerCameraComponent;
FVector2D CameraInput;
FVector2D MovementInput;
void ArcadeCameraYaw(float AxisValue);
void ArcadeCameraPitch(float AxisValue);
void ArcadeMoveForward(float AxisValue);
void ArcadeMoveRight(float AxisValue);
};
CPP
AArcadePlayerCharacter::AArcadePlayerCharacter()
{
// 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;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
RootComponent->bEditableWhenInherited = true;
PlayerCameraGimbalComponent = CreateDefaultSubobject<USceneComponent>(TEXT("PlayerCameraGimbalComponent"));
PlayerCameraGimbalComponent->SetupAttachment(RootComponent);
PlayerCameraGimbalComponent->bEditableWhenInherited = true;
PlayerCameraSpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("PlayerCameraSpringArmComponent"));
PlayerCameraSpringArmComponent->SetupAttachment(PlayerCameraGimbalComponent);
PlayerCameraSpringArmComponent->bEditableWhenInherited = true;
PlayerCameraSpringArmComponent->bInheritYaw = true;
PlayerCameraSpringArmComponent->bInheritPitch = false;
PlayerCameraSpringArmComponent->bInheritRoll = false;
PlayerCameraSpringArmComponent->TargetArmLength = 800.0f;
PlayerCameraSpringArmComponent->SetRelativeLocationAndRotation(FVector(0.0f, 5.0f, -30.0f),FRotator(-30.0f, 0.0f, 0.0f));
PlayerCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("PlayerCameraComponent"));
PlayerCameraComponent->SetupAttachment(PlayerCameraSpringArmComponent, USpringArmComponent::SocketName);
PlayerCameraComponent->SetWorldRotation(FRotator(-20.0f, 0.0f, 0.0f));
PlayerCameraComponent->bEditableWhenInherited = true;
AutoPossessPlayer = EAutoReceiveInput::Player0;
}
// Called when the game starts or when spawned
void AArcadePlayerCharacter::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AArcadePlayerCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
RotatePlayerCamera();
}
void AArcadePlayerCharacter::RotatePlayerCamera()
{
if (!CameraInput.IsZero())
{
PlayerCameraGimbalComponent->AddLocalRotation(FRotator(0.0f,CameraInput.X,0.0f));
PlayerCameraSpringArmComponent->AddLocalRotation(FRotator(CameraInput.Y,0.0f,0.0f));
}
}
// Called to bind functionality to input
void AArcadePlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("ArcadeCameraYaw", this, &AArcadePlayerCharacter::ArcadeCameraYaw);
PlayerInputComponent->BindAxis("ArcadeCameraPitch", this, &AArcadePlayerCharacter::ArcadeCameraPitch);
PlayerInputComponent->BindAxis("ArcadeMoveForward", this, &AArcadePlayerCharacter::ArcadeMoveForward);
PlayerInputComponent->BindAxis("ArcadeMoveRight", this, &AArcadePlayerCharacter::ArcadeMoveRight);
}
void AArcadePlayerCharacter::ArcadeCameraYaw(float AxisValue)
{
CameraInput.X = AxisValue;
}
void AArcadePlayerCharacter::ArcadeCameraPitch(float AxisValue)
{
CameraInput.Y = AxisValue;
}
void AArcadePlayerCharacter::ArcadeMoveForward(float AxisValue)
{
MovementInput.Y = AxisValue;
}
void AArcadePlayerCharacter::ArcadeMoveRight(float AxisValue)
{
MovementInput.X = AxisValue;
}