Hi,
I wanted to do my BaseClass only in c++, so I also had to do the Components in it.
Now my Problem is that if I have more than one Component (or my Pickup component isn’t the RootComponent, I’m unsure) declared withCreateDefaultSubobject,
my engine crashes when starting the game.
I have 3 Classes for this object (BaseWeapon, Pickup and BulletTracer, whereas BaseWeapon beeing the real class and Pickup and BulletTracer are only the components with SkeletalMeshComponent).
BaseWeapon is an AActor, where the only thing happening is the Setup of the Attachments in the Constructor:
.h:
UPROPERTY(VisibleAnywhere)
UPickup* Pickup;
UPROPERTY(VisibleAnywhere)
USkeletalMeshComponent* SkeletalMeshComponent;
UPROPERTY(VisibleAnywhere)
UBulletTracer* BulletTracer;
.cpp:
ABaseWeapon::ABaseWeapon()
{
// 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;
RootComponent = CreateDefaultSubobject<UPickup>(TEXT("Pickup"));
// Both crash wether or not the other component is used
SkeletalMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("SkeletalMeshComp"));
SkeletalMeshComponent->SetupAttachment(RootComponent);
BulletTracer = CreateDefaultSubobject<UBulletTracer>(TEXT("BulletTracerComp"));
}
Pickup ist ein USphereComponent which is responsible for picking up the weapon and it does work completly fine when not having any other component.
But I think it’s still helpful to show the code snippeds:
UPickup::UPickup()
{
PrimaryComponentTick.bCanEverTick = true;
this->OnComponentBeginOverlap.AddDynamic(this, &UPickup::BeginOverlap);
}
void UPickup::BeginOverlap(UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex,
bool bFromSweep,
const FHitResult& SweepResult)
{
if (!OtherActor->GetComponentByClass<UCharacterMovementComponent>()) return;
if (!OtherActor->FindComponentByClass<UCapsuleComponent>()) {
UE_LOG(LogTemp, Display, TEXT("HAHAHAHAHHA"));
return;
}
attachedComponent = OtherActor->FindComponentByClass<UCapsuleComponent>();
this->AttachToComponent(attachedComponent, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
}
Last but not least the BulletTracer, this is an UActorComponent and creates a red Tracer of type Bullet.
The TickComponent is checks if there is a Hit, if the hit has the Tag “Shootable” in it and then prints out its name.
But also I have to mention that I tested what would happen if I removed this part completly, but it still crashed.
void UBulletTracer::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
FHitResult HitResult;
bool hasHit = GetShootableInReach(HitResult);
if (hasHit) {
UPrimitiveComponent* HitComponent = HitResult.GetComponent();
HitComponent->WakeAllRigidBodies();
if(HitResult.GetActor()->ActorHasTag("Shootable")) UE_LOG(LogTemp, Display, TEXT("Object hit: %s"), *HitComponent->GetName());
}
}
and here’s the function that checks if anything is shootable in reach:
bool UBulletTracer::GetShootableInReach(FHitResult& OutHitResult) const {
FVector OwnerStartLocation;
FVector OwnerEndLocation;
if (!GetOwner()->FindComponentByClass<UPickup>()) {
return false;
}
UPickup* pickup = GetOwner()->FindComponentByClass<UPickup>();
if (pickup->attachedComponent && pickup->IsAttachedTo(pickup->attachedComponent)) {
AActor* Player = pickup->attachedComponent->GetOwner();
UCameraComponent* camera = Player->FindComponentByClass<UCameraComponent>();
OwnerStartLocation = camera->GetComponentLocation();
OwnerStartLocation.Z -= 10; // The camera must be 10 units away from the X-origin
OwnerEndLocation = OwnerStartLocation + camera->GetComponentRotation().Vector() * MaxReach;
}
DrawDebugLine(GetWorld(), OwnerStartLocation, OwnerEndLocation, FColor::Red);
float collisionRadius = 30;
return GetWorld()->SweepSingleByChannel(OutHitResult, OwnerStartLocation, OwnerEndLocation,
FQuat::Identity, ECC_GameTraceChannel2, FCollisionShape::MakeSphere(collisionRadius));
}
And if it would help, here the crashreport:
Fatal error: [File:D:\build++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\Templates\Casts.cpp] [Line: 10] Cast of Object /Script/CoreUObject.Default__Object to Actor failed
UnrealEditor_CoreUObject
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
kernel32
ntdll
Another thing to consider is that I had the same setup yesterday of a Pickup as RootComponent and a BulletTracer as an unattached DefaultSubobject and it worked (Even with the same functionality). I think I should really consider having my Project connected to Git/Github so I could stay at the old version.
But that would be all things, I have to say. And I’m very thankful for every help I could get because I can’t really find the solution, even after hours.