Getting the class/type of clicked object/actor

Mainly what I’m trying to do is create a system where you can select different characters in a party with left click or move the selected character with left click if you click on the ground.

I’m trying to do this between scripts, with a parent class for characters and a custom controller for the controls.

The brick wall I’ve run into is how to detect what is being clicked on is in-fact a character and not something else, like the floor because the floor is also an “actor”. The way I’ve tried implementing it most recently is spitting back a compiling error that says, " ‘T’ template parametere to FindComponentByClass must be derived from UActorComponent" and lists Actor.h from the GameFramework as the issue.

Any guidance on this would be greatly appreciated.

This is the controller cpp:

#include "GameController.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "GameDataStruct.h"

AGameController::AGameController() {

}

void AGameController::BeginPlay() {
	
	Super::BeginPlay();

	bShowMouseCursor = true;

	

		if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))

		{
			Subsystem->AddMappingContext(CRPGMapContext, 0);
		}
	
}

void AGameController::Tick(float DeltaTime) {

	Super::Tick(DeltaTime);
	

}

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


	if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(InputComponent))
	{
		EnhancedInputComponent->BindAction(LCAction, ETriggerEvent::Started, this, &AGameController::LeftClick);
	}


}

void AGameController::LeftClick(const FInputActionValue& Value) {
	FHitResult hitRes;
	GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, true, hitRes);
	
	ACharParent* selectedChar = hitRes.GetActor()->FindComponentByClass<ACharParent>();

	if (selectedChar != nullptr) {
		ACharParent* selected = Cast<ACharParent>(hitRes.GetActor());
		this->UnPossess();
		this->Possess(selected);
		UE_LOG(LogTemp, Warning, TEXT("New Character Possesed"));

	}
	else {
		UE_LOG(LogTemp, Warning, TEXT("No possession"));
	}
	

	UE_LOG(LogTemp, Warning, TEXT("PEWPEW"));
	UE_LOG(LogTemp, Warning, TEXT("%s"), hitRes.GetActor());
}

This is the controller h:

#include "CoreMinimal.h"
#include "CharParent.h"
#include "GameFramework/PlayerController.h"
#include "InputActionValue.h"

#include "GameController.generated.h"

class UInputMappingContext;
class UInputAction;
/**
 * 
 */
UCLASS()
class CRPGPROTOFORREAL_API AGameController : public APlayerController
{
	GENERATED_BODY()

public:

	AGameController();

	virtual void BeginPlay() override;

	virtual void SetupInputComponent() override;

	virtual void Tick(float DeltaTime) override;



	

protected:

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
		UInputMappingContext* CRPGMapContext;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
		UInputAction* LCAction;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		ACharParent* otherChar;

	
	

	void LeftClick(const FInputActionValue& Value);
	
};

This is the character parent cpp:


#include "CharParent.h"



// Sets default values
ACharParent::ACharParent()
{
 	// 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 ACharParent::BeginPlay()
{
	Super::BeginPlay();
	targetPOS = GetActorLocation();

	aiCont = Cast<AAIController>(Controller);
}

// Called every frame
void ACharParent::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	if (aiCont != nullptr)
	{
		aiCont->MoveToLocation(targetPOS);
	}
	else {
		UE_LOG(LogTemp, Warning, TEXT("No AI Controller detected"));
	}
	
	
}

This is the character parent h:

#include "CoreMinimal.h"
#include "AIController.h"
#include "GameFramework/Character.h"
#include "CharParent.generated.h"

UCLASS()
class CRPGPROTOFORREAL_API ACharParent : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	ACharParent();

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		FString charType;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		FVector targetPOS;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		AAIController* aiCont;



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

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

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

};

Bolded the primary issue/error code so it’s easier to understand.