Reputation: 13
I'm trying to learn C++/UE4 for the first time, and the code provided in the tutorial (in their own documentation) throws errors. How can I fix this and/or find a tutorial that works?
I'm attempting to work through the tutorial at https://docs.unrealengine.com/en-US/Programming/Tutorials/PlayerInput/index.html, but the code provided in Step 1 throws errors.
I have tried the 'potential fixes' and looked around online but haven't found anything to fix the error.
AMyPawn::AMyPawn() { // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true;
// Set this pawn to be controlled by the lowest-numbered player
AutoPossessPlayer = EAutoReceiveInput::Player0;
// Create a dummy root component we can attach things to.
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
// Create a camera and a visible object
UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera"));
OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent"));
// Attach our camera and visible object to our root component. Offset and rotate the camera.
OurCamera->SetupAttachment(RootComponent);
OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f));
OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f));
OurVisibleComponent->SetupAttachment(RootComponent);
}
Error C2065 'UCameraComponent': undeclared identifier
Error C2065 'OurCamera': undeclared identifier
Error C2672 'UObject::CreateDefaultSubobject': no matching overloaded function found
Error C2974 'UObject::CreateDefaultSubobject': invalid template argument for 'TReturnType', type expected
Error MSB3075 The command ""C:\Program Files\Epic Games\UE_4.22\Engine\Build\BatchFiles\Build.bat" SecondUnrealProjectEditor Win64 Development -Project="C:\Users...\SecondUnrealProject\SecondUnrealProject.uproject" -WaitMutex -FromMsBuild" exited with code 5. Please verify that you have sufficient rights to run this command.
I expected the code to run without errors as I am following the tutorial exactly (and have in fact copy-pasted the 'working' code to check that I didn't change anything by accident)
Upvotes: 1
Views: 4787
Reputation: 67
I have also run into this issue. I have completed the tutorial with some modifications. Visual Studios 2019 14.24.28315 UE4 4.24
MyPawn.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/Character.h"
#include "MyPawn.generated.h"
UCLASS()
class HOWTO_PLAYERINPUT_API AMyPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AMyPawn();
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;
UPROPERTY(EditAnywhere)
USceneComponent* OurVisibleComponent;
//Input functions
void Move_XAxis(float AxisValue);
void Move_YAxis(float AxisValue);
void StartGrowing();
void StopGrowing();
//Input variables
FVector CurrentVelocity;
bool bGrowing;
};
MyPawn.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyPawn.h"
#include "Camera/CameraComponent.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
AMyPawn::AMyPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Set this pawn to be controlled by the lowest-numbered player
AutoPossessPlayer = EAutoReceiveInput::Player0;
// Create a dummy root component we can attach things to.
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
// Create a camera and a visible object
UPROPERTY(EditAnywhere)
UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera"));
OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent"));
// Attach our camera and visible object to our root component. Offset and rotate the camera.
OurCamera->SetupAttachment(RootComponent);
OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f));
OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f));
OurVisibleComponent->SetupAttachment(OurCamera);
OurVisibleComponent->SetRelativeLocation(FVector(268.0f, 0.0f, -14.14f));
OurVisibleComponent->SetRelativeRotation(FRotator(45.0f, 0.0f, 0.0f));
}
// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Handle growing and shrinking based on our "Grow" action
float CurrentScale = OurVisibleComponent->GetComponentScale().X;
if (bGrowing)
{
// Grow to double size over the course of one second
CurrentScale += DeltaTime;
}
else
{
// Shrink half as fast as we grow
CurrentScale -= (DeltaTime * 0.5f);
}
// Make sure we never drop below our starting size, or increase past double size.
CurrentScale = FMath::Clamp(CurrentScale, 1.0f, 2.0f);
OurVisibleComponent->SetWorldScale3D(FVector(CurrentScale));
// Handle movement based on our "MoveX" and "MoveY" axes
if (!CurrentVelocity.IsZero())
{
FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
SetActorLocation(NewLocation);
}
}
// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Respond when our "Grow" key is pressed or released.
PlayerInputComponent->BindAction("Grow", IE_Pressed, this, &AMyPawn::StartGrowing);
PlayerInputComponent->BindAction("Grow", IE_Released, this, &AMyPawn::StopGrowing);
// Respond every frame to the values of our two movement axes, "MoveX" and "MoveY".
PlayerInputComponent->BindAxis("MoveX", this, &AMyPawn::Move_XAxis);
PlayerInputComponent->BindAxis("MoveY", this, &AMyPawn::Move_YAxis);
}
void AMyPawn::Move_XAxis(float AxisValue)
{
// Move at 100 units per second forward or backward
CurrentVelocity.X = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}
void AMyPawn::Move_YAxis(float AxisValue)
{
// Move at 100 units per second right or left
CurrentVelocity.Y = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}
void AMyPawn::StartGrowing()
{
bGrowing = true;
}
void AMyPawn::StopGrowing()
{
bGrowing = false;
}
I Just find it insane that every time UE4 updates basically every tutorial goes to Hell. *NOTE: I fumbled my way through completing this tutorial. I am meh at UE4 and did not take the time to "properly" write this code, so if anything is wrong style/convention wise, I'm sorry ;)
Upvotes: 1
Reputation: 8598
The first error means that the compiler can't find the declaration for UCameraComponent
, the other errors are simply follow-up errors.
You need to add the following include to your MyPawn.cpp
:
#include "Camera/CameraComponent.h"
After fixing that you'll get another error, this time because the declaration for UStaticMeshComponent
is missing. For that you need the following include:
#include "Components/StaticMeshComponent.h"
The error messages are different, because in the first case the compiler wants to instantiate an object of an unknown type, which is not possible, while in the latter case the compiler wants to assign a pointer of the unknown type UStaticMeshComponent
to another pointer of the known type USceneComponent
, and it doesn't know that UStaticMeshComponent
can be cast to USceneComponent
.
I agree that it's bad that the tutorial missed this, however finding a missing include is fairly easy with the right tool. In Visual Studio you can simply click on any type (e.g. UCameraComponent
) while holding Ctrl
and it will either directly go to the declaration, or it will show you a list of files with potential declarations.
In Unreal it's also generally the case that for every component the include file has that component's name, so for UCameraComponent
that's CameraComponent.h
, which resides in the subfolder Camera
.
Upvotes: 3