Ok so in the past I tried to learn Unreal Engine (about a year ago or so) and I had learned about the IWYU header practice adopted by Unreal. To be honest at the time, it confused me a lot and I ran into double declaration problems or similar and gave up.
I am back to try learn again
But this time I was ready for doing the headers (I think!). However, in my first test I write this class and it appears I do not need to #include for the static mesh. (my pointer declaration named âcube_meshâ This code appears to me to run and function perfectly well without the #includeâŚ
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Contestant.generated.h"
UCLASS()
class SMASHTV_API AContestant : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AContestant();
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;
void MoveForward (float AxisValue);
void MoveRight(float AxisValue);
void MoveTurn(float AxisValue);
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
UStaticMeshComponent* cube_mesh;
};
and the cppâŚ
#include "Contestant.h"
// Sets default values
AContestant::AContestant()
{
// 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;
cube_mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("cubemesh"));
cube_mesh->SetupAttachment(GetMesh());
}
// Called when the game starts or when spawned
void AContestant::BeginPlay()
{
Super::BeginPlay();
}
void AContestant::MoveForward(float AxisValue)
{
if((Controller != nullptr) && (AxisValue != 0.0f))
{
const FRotator Rotation = Controller->GetControlRotation();
const FRotator Yaw(0, Rotation.Yaw, 0);
const FVector Direction = FRotationMatrix(Yaw).GetUnitAxis(EAxis::X);
AddMovementInput(Direction, AxisValue);
}
}
void AContestant::MoveRight(float AxisValue)
{
if((Controller != nullptr) && (AxisValue != 0.0f))
{
const FRotator Rotation = Controller->GetControlRotation();
const FRotator Yaw(0, Rotation.Yaw, 0);
const FVector Direction = FRotationMatrix(Yaw).GetUnitAxis(EAxis::Y);
AddMovementInput(Direction, AxisValue);
}
}
void AContestant::MoveTurn(float AxisValue)
{
}
// Called every frame
void AContestant::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AContestant::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("Vertical", this, &AContestant::MoveForward);
PlayerInputComponent->BindAxis("Horizontal", this, &AContestant::MoveRight);
}
) which doesnât build source directly, but combines cpp files into larger cpp and compiles those instead. Some of the reasons for this include build time, link time and other optimizations during compilation. The downside is that it can really mess with your builds because itâs an automated process. You can be building just fine, edit A.cpp and suddenly B.cpp will have a compile error because of a missing include because B was getting one of itâs includes from another cpp in the unity source file but B is now in a different unity file or itâs been re-ordered!