UnrealEditor_SonicUnleashedRemake!ACameraActor::GetCameraComponent() [G:\EpicGames\UE_5.4\Engine\Source\Runtime\Engine\Classes\Camera\CameraActor.h:75]
UnrealEditor_SonicUnleashedRemake!ASonicCharacterComponent::ASonicCharacterComponent() [G:\.FinalSonicUnleashedRemakeProject\SonicUnleashedRemake\Source\SonicUnleashedRemake\Private\Sonic\SonicCharacterComponent.cpp:34]

how do i fix this??
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "BoostComponent.h"
#include "ESonicCharacterState.h"
#include "HomingAttackComponent.h"
#include "LightSpeedDashComponent.h"
#include "WallJumpComponent.h"
#include "PickUpComponent.h"
#include "SonicCameraComponent.h"
#include "SonicMovementComponent.h"
#include "SpeedActorInteractionsComponent.h"
#include "SonicCharacterComponent.generated.h"

class UCameraComponent;

UCLASS()
class SONICUNLEASHEDREMAKE_API ASonicCharacterComponent : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	ASonicCharacterComponent(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Sonic")
		EFEeSonicCharacterState CurrentState;

	

	//components
	UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = "Boost")
		UBoostComponent* BoostComponent;
	UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = "HomingAttack")
		UHomingAttackComponent* HomingAttackComponent;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SpeedItemInteractions")
		USpeedActorInteractions* SpeedActorInteractionsComponent;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PickUpComponent")
		UPickUpComponent* PickUpComponent;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "LightSpeedDashComponent")
		ULightSpeedDashComponent* LightSpeedDashComponent;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "WallJumpComponent")
		UWallJumpComponent* WallJumpComponent;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Sonic")
		USonicMovementComponent* SonicMovement;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "CameraComponent")
		USonicCameraComponent* SonicCameraComponent;
	
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Sonic Movement")
	UArrowComponent* FancyArrow;



protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Sonic")
	USpringArmComponent* SpringArmComponent;

	
	void StatusHandler();
	bool StateInAir();

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
	void MoveForward(float Value);
	void MoveRight(float Value);
	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	virtual __override void Jump() override;
	virtual __override void StopJumping() override;
	virtual __override void Landed(const FHitResult& Hit) override;
	
	//functions to be called in the blueprint
	
	UFUNCTION(BlueprintCallable, Category = "Sonic") // launch sonic can be found in the movement component
		void LaunchSonic(float Speed, FVector Direction, float OutOfControlTime, float KeepVelocityTime,
			bool bAlignToMovementDirection, float HomingCooldown, bool bCanHomingAttackAfterLaunch = true, bool bCanAirDashAfterLaunch = true, bool bMaintainMomentum = false);

	
	UFUNCTION(BlueprintCallable, Category = "Sonic")
		void SetLocationAboveActor(AActor* ActorToStandAbove, float HightOffset);
	

	UPROPERTY(Blueprintable, BlueprintReadWrite, Category = "Sonic")
		bool bCanMove;


};

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


#include "Sonic/SonicCharacterComponent.h"

#include "Camera/CameraComponent.h"
#include "Sonic/SonicMovementComponent.h"
#include "GameFramework/SpringArmComponent.h"

// Sets default values
ASonicCharacterComponent::ASonicCharacterComponent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer.SetDefaultSubobjectClass<USonicMovementComponent>(ACharacter::CharacterMovementComponentName))
{

	//setup components
	BoostComponent = CreateDefaultSubobject<UBoostComponent>(TEXT("BoostComponent"));
	HomingAttackComponent = CreateDefaultSubobject<UHomingAttackComponent>(TEXT("HomingAttackComponent"));
	SpeedActorInteractionsComponent = CreateDefaultSubobject<USpeedActorInteractions>(TEXT("SpeedActorInteractions"));
	PickUpComponent = CreateDefaultSubobject<UPickUpComponent>(TEXT("PickUpComponent"));
	LightSpeedDashComponent = CreateDefaultSubobject<ULightSpeedDashComponent>(TEXT("LightSpeedDashComponent"));
	WallJumpComponent = CreateDefaultSubobject<UWallJumpComponent>(TEXT("WallJumpComponent"));
	SonicMovement = Cast<USonicMovementComponent>(GetCharacterMovement());
	SonicCameraComponent = CreateDefaultSubobject<USonicCameraComponent>(TEXT("SonicCameraComponent"));
	FancyArrow = CreateDefaultSubobject<UArrowComponent>(TEXT("DebugArrow"));
	PrimaryActorTick.bCanEverTick = true;
	CurrentState = EFEeSonicCharacterState::Idle; //set the current state to idle
	bCanMove = true;

	SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComponent"));
	SpringArmComponent->SetupAttachment(RootComponent);
	SpringArmComponent->TargetArmLength = 500.0f;
	SpringArmComponent->bUsePawnControlRotation = true;
	
	SonicCameraComponent->Camera->GetCameraComponent()->SetupAttachment(SpringArmComponent);
	SonicCameraComponent->Camera->GetCameraComponent()->bUsePawnControlRotation = false;
	
}



// Called when the game starts or when spawned
void ASonicCharacterComponent::BeginPlay()
{
	Super::BeginPlay();
	if (SonicCameraComponent && SpringArmComponent && SonicCameraComponent->Camera->GetCameraComponent())
	{
		SonicCameraComponent->SetupCamera(this, SpringArmComponent, SonicCameraComponent->Camera);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("ASonicCharacterComponent::BeginPlay - Missing required components"));
	}
}

void ASonicCharacterComponent::StatusHandler()
{
	if (!SonicMovement) return;
	
	float CurrentSpeed = SonicMovement->GetForwardSpeed();
	bool bIsFalling = SonicMovement->IsFalling();

	constexpr float MovementThreshold = 1.0f;

	//print current state, and current speed
	GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Red, FString::Printf(TEXT("Current State: %s"), *UEnum::GetValueAsString(CurrentState)));
	GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Red, FString::Printf(TEXT("Current Speed: %f"), CurrentSpeed));

	if (CurrentSpeed > MovementThreshold && CurrentState == EFEeSonicCharacterState::Idle)//if idle then set to moving
	{
		if (CurrentState != EFEeSonicCharacterState::MovingOnGround)
		{
			CurrentState = EFEeSonicCharacterState::MovingOnGround;
		}
	}
	//if we are in ground movement state, but we stand still, set to idle
	else if (CurrentSpeed <= MovementThreshold && CurrentState == EFEeSonicCharacterState::MovingOnGround)
	{
		CurrentState = EFEeSonicCharacterState::Idle;
	}

	//if we are in ground movement, but we are in the air, set to falling
	if (CurrentState == EFEeSonicCharacterState::MovingOnGround && GetCharacterMovement()->IsFalling())
	{
		CurrentState = EFEeSonicCharacterState::Falling;
	}

	//if the state we are currently in is listed as an in air state, but we are no longer in the air, reset to idle
	if (StateInAir() && !GetCharacterMovement()->IsFalling())
	{
		CurrentState = EFEeSonicCharacterState::Idle;
		
	}
}

bool ASonicCharacterComponent::StateInAir()
{
	//if the state is either jumping or falling, return true
	if (CurrentState == EFEeSonicCharacterState::Jumping ||
		CurrentState == EFEeSonicCharacterState::Falling ||
		CurrentState == EFEeSonicCharacterState::HomingAttacking||
		CurrentState == EFEeSonicCharacterState::AirBoosting||
		CurrentState == EFEeSonicCharacterState::AirDashing)
		//don't include light speed dashing because we want to be able to dash from the ground
	{
		return true;
	}
	return false;
	
}

// Called every frame
void ASonicCharacterComponent::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	StatusHandler();
	FancyArrow->SetWorldLocation(GetActorLocation());
}


void ASonicCharacterComponent::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	PlayerInputComponent->BindAxis("MoveForward", this, &ASonicCharacterComponent::MoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &ASonicCharacterComponent::MoveRight);
}

void ASonicCharacterComponent::MoveForward(float value)
{
	SonicMovement->MoveForward(value);
}

void ASonicCharacterComponent::MoveRight(float value)
{
	SonicMovement->MoveRight(value);
}

void ASonicCharacterComponent::Jump()
{
	if(SonicMovement->IsFalling())return;
	Super::Jump();
	SonicMovement->Jump();
}

void ASonicCharacterComponent::StopJumping()
{
	Super::StopJumping();
}

void ASonicCharacterComponent::Landed(const FHitResult& Hit)
{
	Super::Landed(Hit);
	SonicMovement->OnLanded();
}

void ASonicCharacterComponent::LaunchSonic(float Speed, FVector Direction, float OutOfControlTime, float KeepVelocityTime,
										   bool bAlignToMovementDirection, float HomingCooldown, bool bCanHomingAttackAfterLaunch,
										   bool bCanAirDashAfterLaunch, bool bMaintainMomentum)
{
	SonicMovement->LaunchSonic(Speed, Direction, OutOfControlTime, KeepVelocityTime, bAlignToMovementDirection, HomingCooldown, bCanHomingAttackAfterLaunch, bCanAirDashAfterLaunch, bMaintainMomentum);
}

void ASonicCharacterComponent::SetLocationAboveActor(AActor* ActorToStandAbove, float HightOffset)
{
	FVector DesiredLocation = ActorToStandAbove->GetActorLocation();
	FVector UpVector = ActorToStandAbove->GetActorUpVector();
	DesiredLocation += UpVector * HightOffset;
	SetActorLocation(DesiredLocation);
}



#pragma once

#include "CoreMinimal.h"
#include "Camera/CameraActor.h"
#include "Components/SplineComponent.h"
#include "UnleashedCamera.generated.h"

UENUM(BlueprintType)
enum class EUnleashedCameraType : uint8
{
	SplineCamera,
	FixedCamera,
	FollowCamera
};

UCLASS()
class SONICUNLEASHEDREMAKE_API AUnleashedCamera : public ACameraActor
{
	GENERATED_BODY()
    
public:
	AUnleashedCamera();

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Settings")
	EUnleashedCameraType CameraType;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Settings", meta = (EditCondition = "CameraType == EUnleashedCameraType::Spline"))
	USplineComponent* SplinePath;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera Settings")
	bool bLookAtSonic;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera Settings")
	class ASonicCharacterComponent* SonicCharacter;

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


protected:
	virtual void BeginPlay() override;
	virtual void Tick(float DeltaTime) override;

private:
	void UpdateSplineCamera(float DeltaTime);
	void UpdateFollowCamera(float DeltaTime);
	void LookAtTarget(AActor* Target);
};

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


#include "UnleashedCamera.h"
#include "Sonic/SonicCharacterComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMathLibrary.h"

AUnleashedCamera::AUnleashedCamera()
{
	PrimaryActorTick.bCanEverTick = true;
	bLookAtSonic = false;
	//get camera actor
	RootComponent = GetCameraComponent();
}

void AUnleashedCamera::BeginPlay()
{
	Super::BeginPlay();
	//find sonic
	SonicCharacter = Cast<ASonicCharacterComponent>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
	if (!SonicCharacter)
	{
		UE_LOG(LogTemp, Error, TEXT("SonicCharacter not found in camera"));
	}
}

void AUnleashedCamera::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	if (bLookAtSonic)
	{
		LookAtTarget(SonicCharacter);
	}

	switch(CameraType)
	{
		case EUnleashedCameraType::SplineCamera:
			UpdateSplineCamera(DeltaTime);
			break;
		case EUnleashedCameraType::FollowCamera:
			UpdateFollowCamera(DeltaTime);
			break;
		default:
			break;
	}
}

void AUnleashedCamera::UpdateSplineCamera(float DeltaTime)
{
	//todo
}

void AUnleashedCamera::UpdateFollowCamera(float DeltaTime)
{
	//todo
}

void AUnleashedCamera::LookAtTarget(AActor* Target)
{
	if (Target)
	{
		FRotator LookAtRotation = UKismetMathLibrary::FindLookAtRotation(GetActorLocation(), Target->GetActorLocation());
		SetActorRotation(LookAtRotation);
	}
}