How can I create a player input component in an actor class?

Well, in a word, no.

Input components don’t make sense on objects that don’t somehow belong to the player. If they’re not the player (i.e., a player controller, or a pawn possessed by a player controller) then who are they getting this input from? Since Controllers can’t possess Actors (this is the defining characteristic which separates an actor form a pawn) then InputComponents don’t make sense to be on Actors.

You need to leave your input stuff on the pawn, and then use that input in the camera director. For example, you could create a function on the pawn which takes in a pointer to an ACameraDirector, and then binds actions from the player’s input component to the ACameraDirector’s StartSwitch and StopSwitch functions. Then, in the level blueprint, when the player spawns, call the function and pass it an ACameraDirector which you’ve preplaced in the level.

You can just change your CameraDirector to inherit from Pawn.

Change
class HOWTO_AUTOCAMERA_API ACameraDirector : public AActor

To

class HOWTO_AUTOCAMERA_API ACameraDirector : public APawn

And

 #include "GameFramework/Actor.h"

to

 #include "GameFramework/Pawn.h"

and then recompile.

There should be a SetViewTarget function on the PlayerController. Camera documentation is here: Using Cameras | Unreal Engine Documentation

Hi UE4 community!

So I’m experimenting with one of Unreal Docs tutorials, the Game-Controlled Camera one. I first modified the camera-switching conditional in the Tick() so that it smoothly runs between Camera One and Camera Two, instead of just blending to Camera Two then jerking back to Camera One. That worked fine. Then, to challenge myself, I wanted to try making it depend on a button prompt: pressing x would switch the cameras instead of a timer. It seemed simple enough, but I now realize that since the CameraDirector’s parent class is the actor and not the pawn, there is no player input component, so my ‘Super::SetupPlayerInputComponent(InputComponent)’ is triggering a syntax error (line 88). Is there any way to create the input component? Here is my code:

CameraDirector.h

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

#pragma once

#include "GameFramework/Actor.h"
#include "CameraDirector.generated.h"

UCLASS()
class HOWTO_AUTOCAMERA_API ACameraDirector : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ACameraDirector();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;
    
    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent);

    
    //These makes it possible to drag and drop cameras into the class
    UPROPERTY(EditAnywhere)
    AActor* CameraOne;
    
    UPROPERTY(EditAnywhere)
    AActor* CameraTwo;
    
    float TimeToNextCameraChange;
    
    //Button for switching camera manually
    //Input functions
    void StartSwitch();
    void StopSwitch();
    
    //Input variable
    bool bSwitching;
    
	
};

CameraDirector.cpp:

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

#include "HowTo_AutoCamera.h"
#include "CameraDirector.h"
#include "Kismet/GameplayStatics.h"


// Sets default values
ACameraDirector::ACameraDirector()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
    
    //Set this up to be controlled by the lowest-numbered player
    //AutoPosessPlayer = EAutoReceiveInput::Player0;
    
    

}

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

// Called every frame
void ACameraDirector::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );
    
    const float SmoothBlendTime = 0.75f;
    if(bSwitching)
    {
        //Locates the player actor
        APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);
        if(OurPlayerController)
        {
            if((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr))
            {
                //Cut instantly to CameraONe
                OurPlayerController->SetViewTargetWithBlend(CameraOne, SmoothBlendTime);
            }
            else if((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr))
            {
                OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime);
            }
        }

    }
    
    
    /* All of this commented out is from the original tutorial
    const float TimeBetweenCameraChanges = 2.0f;
    const float SmoothBlendTime = 0.75f;
    
    
    TimeToNextCameraChange -= DeltaTime;
    
    if(TimeToNextCameraChange <= 0.0f)
    {
        TimeToNextCameraChange += TimeBetweenCameraChanges;
        
        
        //Locates the player actor
        APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);
        if(OurPlayerController)
        {
            if((OurPlayerController->GetViewTarget() != CameraOne) && (CameraOne != nullptr))
            {
                //Cut instantly to CameraONe
                OurPlayerController->SetViewTargetWithBlend(CameraOne, SmoothBlendTime);
            }
            else if((OurPlayerController->GetViewTarget() != CameraTwo) && (CameraTwo != nullptr))
            {
                OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime);
            }
        }
    }*/
    

}

// Called to bind functionality to input
void ACameraDirector::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
    Super::SetupPlayerInputComponent(InputComponent);
    
    // Respond when the "Switch" key is pressed or released
    InputComponent->BindAction("Switch", IE_Pressed, this, &ACameraDirector::StartSwitch);
    InputComponent->BindAction("Switch", IE_Released, this, &ACameraDirector::StopSwitch);
    
    
}

void ACameraDirector::StartSwitch()
{
    bSwitching = true;
}

void ACameraDirector::StopSwitch()
{
    bSwitching = false;
}

I had a feeling this was the case. Is it possible to repeat the tutorial with a pawn class instead of an actor class? As for your suggestion, how do I set up the pointer in that function? I’ve yet to do anything that invokes functions or variables from other scripts.

It’s that simple? So I added those lines and recompiled: successful! So now, when I hit play, I take control of the CameraDirector, and I’m seeing through the CameraDirector’s POV (I’m guessing game objects inherit a camera component automatically from the pawn parent class?). Is there a way to establish my POV as either of my two cameras?

Hey! I know its an old post, but maybe someone will need this (btw all what I’m saying works in UE_4.26).
So,

you CAN make actor listen to your input.
Every actor has already defined UInputComponent.
You need to do, is initiate it in your actor constructor

InputComponent = CreateDefaultSubobject<UInputComponent>("Input Component");

Then you have to create your own SetupPlayerInputComponent function.
The most important thing about this function is that it needs to take UInputComponent PlayerInputComponent* parameter.

Inside, just do as you would do it for a pawn.

PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AYourActor::CustomFunction);

Then go back you your constructor and call your SetupPlayerInputComponent function

So .h file should look like this

void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent);

And .cpp file

// In constructor:

InputComponent = CreateDefaultSubobject<UInputComponent>("Input Component");
SetupPlayerInputComponent(InputComponent);

//------------------------------------------------------------------
void ACheckpoint::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
	PlayerInputComponent->BindAction("SaveGame", IE_Pressed, this, &ACheckpoint::SaveGame);
}

Oh, and most important thing! You have to call

EnableInput(APlayerController* PlayerController)

function in this actor in order to make it listen to your input.

After Lot of Effort and struggle with Unreal And even Watch Courses I Found The Easiest Way.

First Include : #include "Components/InputComponent.h"

In Your Header File (YourClass.h) :

void SetupPlayerInputComponent();

In Your cpp File (YourClass.cpp) :

In beginPlay() :

SetupPlayerInputComponent();

Final Part in Your cpp File :

void ADoorActor::SetupPlayerInputComponent()
{
	InputComponent = GetWorld()->GetFirstPlayerController()->FindComponentByClass<UInputComponent>();
	
	InputComponent->BindAction("OpenDoor", IE_Pressed, this, &ADoorActor::GetIsPressed);
}

I Hope You Enjoy ! :slight_smile: