Search code examples
c++visual-studio-codeunreal-engine4

How to fix 'Cannot access private member declared in class' error in Unreal & C++


I am currently learning Unreal and working with C++ and when creating a collision box I am receiving an 'Error C2248: 'UPrimitiveComponent::bGenerateOverlapEvents': cannot access private member declared in class 'UPrimitiveComponent' The error is showing at line 18 in the ShipController.cpp file.

When reading around it was suggested that instead of using 'bGenerateOverlapEvents' to use 'SetGenerateOverlapEvents' instead however whilst this compiled correctly the collision box didn't not function properly.

Ship Controller Header File:

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "ShipController.generated.h"

UCLASS()
class BASICSHOOTER_API AShipController : public APawn
{
    GENERATED_BODY()

public:
    // Sets default values for this pawn's properties
    AShipController();

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)
    UShapeComponent* CollisionBox;

    UPROPERTY(EditAnywhere)
    float Speed = 10.0f;

    UPROPERTY(EditAnywhere, Category="Spawning")
            TSubclassOf<class ABulletController> BulletBlueprint;

    void Move_XAxis(float AxisValue);
    void Move_YAxis(float AxisValue);
    void OnShoot();

    FVector CurrentVelocity;

    bool Died;
    UFUNCTION()
    void OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
};

Ship Controller Cpp file

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

#include "ShipController.h"
#include "BulletController.h"
#include "EnemyController.h"
#include "Components/BoxComponent.h"
#include "Kismet/GameplayStatics.h"


// Sets default values
AShipController::AShipController()
{
    // 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;

    CollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("Root"));
    CollisionBox->bGenerateOverlapEvents = true;
    CollisionBox->OnComponentBeginOverlap.AddDynamic(this, &AShipController::OnOverlap);

    AutoPossessPlayer = EAutoReceiveInput::Player0;
}

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

}

// Called every frame
void AShipController::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    if (!CurrentVelocity.IsZero())
    {
        FVector NewLocation = GetActorLocation() + Speed * CurrentVelocity * DeltaTime;

        SetActorLocation(NewLocation);

    }

}

// Called to bind functionality to input
void AShipController::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    InputComponent->BindAxis("MoveX", this, &AShipController::Move_XAxis);
    InputComponent->BindAxis("MoveY", this, &AShipController::Move_YAxis);
    InputComponent->BindAction("Shoot", IE_Pressed, this, &AShipController::OnShoot);
}

void AShipController::Move_XAxis(float AxisValue)
{
    CurrentVelocity.X = AxisValue * 100.0f;
}

void AShipController::Move_YAxis(float AxisValue)
{
    CurrentVelocity.Y = AxisValue * 100.0f;
}

void AShipController::OnShoot()
{
    UWorld* World = GetWorld();

    if (World)
    {
        FVector Location = GetActorLocation();
        World->SpawnActor<ABulletController>(BulletBlueprint, Location, FRotator::ZeroRotator);
    }
}

void AShipController::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
    if (OtherActor->IsA(AEnemyController::StaticClass()))
    {
        Died = true;
        this->SetActorHiddenInGame(true);

        UGameplayStatics::SetGamePaused(GetWorld(), true);

    }

}

Enemy Controller Header File

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "EnemyController.generated.h"

UCLASS()
class BASICSHOOTER_API AEnemyController : public AActor
{
    GENERATED_BODY()

public: 
    // Sets default values for this actor's properties
    AEnemyController();

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

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

    UPROPERTY(EditAnywhere)
    UShapeComponent* RootBox;

    UPROPERTY(EditAnywhere)
    float Speed = -200.0f;
};

Enemy Controller Cpp File

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


#include "EnemyController.h"
#include "Components/BoxComponent.h"


// Sets default values
AEnemyController::AEnemyController()
{
    // 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;

    RootBox = CreateDefaultSubobject<UBoxComponent>(TEXT("Root"));
}

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

}

// Called every frame
void AEnemyController::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    FVector NewLocation = GetActorLocation();

    NewLocation.X += Speed * DeltaTime;
    SetActorLocation(NewLocation);

    if (NewLocation.X < -600.0f)
    {
        this->Destroy();
    }
}


I expect the output to be when an object of class EnemyController touches an object of class ShipController that the game will pause and that the object of class ShipController will be hidden in game.


Solution

  • Using SetGenerateOverlapEvents(true); instead of bGenerateOverlapEvents = true; did work. For some reason I had set the objects at different heights and the collision boxes were not colliding which is why it didn't appear to work. Thanks for the comments and advice!