如何修复 Unreal 和 C++ 中的 'Cannot access private member declared in class' 错误
How to fix 'Cannot access private member declared in class' error in Unreal & C++
我目前正在学习 Unreal 并使用 C++,在创建碰撞盒时我收到“错误 C2248:'UPrimitiveComponent::bGenerateOverlapEvents':无法访问在 class 'UPrimitiveComponent' 中声明的私有成员
错误显示在 ShipController.cpp 文件的第 18 行。
阅读时建议不要使用 'bGenerateOverlapEvents' 而应使用 'SetGenerateOverlapEvents',但是虽然编译正确,但碰撞盒无法正常工作。
船舶控制器头文件:
// 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);
};
船舶控制器 Cpp 文件
// 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);
}
}
敌方控制器头文件
// 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;
};
敌方控制器 Cpp 文件
// 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();
}
}
我希望输出是当 class EnemyController 的对象接触到 class ShipController 的对象时游戏将暂停并且 class ShipController 的对象将被隐藏在游戏中。
使用 SetGenerateOverlapEvents(true);
而不是 bGenerateOverlapEvents = true;
确实有效。
出于某种原因,我将对象设置在不同的高度并且碰撞盒没有发生碰撞,这就是它似乎不起作用的原因。
感谢您的意见和建议!
我目前正在学习 Unreal 并使用 C++,在创建碰撞盒时我收到“错误 C2248:'UPrimitiveComponent::bGenerateOverlapEvents':无法访问在 class 'UPrimitiveComponent' 中声明的私有成员 错误显示在 ShipController.cpp 文件的第 18 行。
阅读时建议不要使用 'bGenerateOverlapEvents' 而应使用 'SetGenerateOverlapEvents',但是虽然编译正确,但碰撞盒无法正常工作。
船舶控制器头文件:
// 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);
};
船舶控制器 Cpp 文件
// 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);
}
}
敌方控制器头文件
// 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;
};
敌方控制器 Cpp 文件
// 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();
}
}
我希望输出是当 class EnemyController 的对象接触到 class ShipController 的对象时游戏将暂停并且 class ShipController 的对象将被隐藏在游戏中。
使用 SetGenerateOverlapEvents(true);
而不是 bGenerateOverlapEvents = true;
确实有效。
出于某种原因,我将对象设置在不同的高度并且碰撞盒没有发生碰撞,这就是它似乎不起作用的原因。
感谢您的意见和建议!