I got this crash:
Access violation - code c0000005
(first/second chance not available)
STAKERII_Win64_Shipping!UDecalComponent::SetLifeSpan()
STAKERII_Win64_Shipping!CreateDecalComponent() STAKERII_Win64_Shipping!UGameplayStatics::SpawnDecalAttached()
STAKERII_Win64_Shipping!ASTAKERII_Effect::BeginPlay()
[d:\source\STAKERII\effects\STAKERII_Effect.cpp:74]
STAKERII_Win64_Shipping!AActor::PostActorConstruction()
STAKERII_Win64_Shipping!AActor::FinishSpawning()
STAKERII_Win64_Shipping!UGameplayStatics::FinishSpawningActor()
STAKERII_Win64_Shipping!ASTAKERII_Bomb_Base::Explode()
Chain:
void ASTAKERII_Bomb_Base::Explode(const FHitResult& Impact)
{
if (ExplosionTemplate)
{
const FRotator SpawnRotation = Impact.ImpactNormal.Rotation();
FTransform SpawnTM(SpawnRotation, ImpactLocation);
class ASTAKERII_ExplosionEffects* EffectActor = Cast<ASTAKERII_ExplosionEffects>(UGameplayStatics::BeginDeferredActorSpawnFromClass(this, ExplosionTemplate, SpawnTM));
if (EffectActor)
{
EffectActor->SetSurfaceHit(Impact);
EffectActor->SetDamageTypeClass(DamageTypeClass);
UGameplayStatics::FinishSpawningActor(EffectActor, SpawnTM);
}
}
void ASTAKERII_Effect::BeginPlay()
{
Super::BeginPlay();
if (DefaultFX)
{
UGameplayStatics::SpawnEmitterAtLocation(this, DefaultFX, GetActorLocation(), GetActorRotation());
}
if (DefaultSound)
{
UGameplayStatics::PlaySoundAtLocation(this, DefaultSound, GetActorLocation());
}
if (DefaultDecal.DecalMaterial)
{
FRotator RandomDecalRotation = SurfaceHit.ImpactNormal.Rotation();
RandomDecalRotation.Roll = FMath::FRandRange(-180.0f, 180.0f);
UGameplayStatics::SpawnDecalAttached(DefaultDecal.DecalMaterial, FVector(DefaultDecal.DecalSize, DefaultDecal.DecalSize, 1.0f),
SurfaceHit.Component.Get(), SurfaceHit.BoneName,
SurfaceHit.ImpactPoint, RandomDecalRotation, EAttachLocation::KeepWorldPosition,
DefaultDecal.LifeSpan);
}
}
UGameplayStatics::SpawnDecalAttached calls decal component creaton:
else
{
UDecalComponent* DecalComp = CreateDecalComponent(DecalMaterial, DecalSize, AttachToComponent->GetWorld(), AttachToComponent->GetOwner(), LifeSpan);
DecalComp->AttachTo(AttachToComponent, AttachPointName);
No pointer check here, so it should be created ever
UDecalComponent* CreateDecalComponent(class UMaterialInterface* DecalMaterial, FVector DecalSize, UWorld* World, AActor* Actor, float LifeSpan)
{
UDecalComponent* DecalComp = NewObject<UDecalComponent>((Actor ? Actor : (UObject*)World));
DecalComp->bAllowAnyoneToDestroyMe = true;
DecalComp->DecalMaterial = DecalMaterial;
DecalComp->DecalSize = DecalSize;
DecalComp->bAbsoluteScale = true;
DecalComp->RegisterComponentWithWorld(World);
if (LifeSpan > 0.f)
{
DecalComp->SetLifeSpan(LifeSpan);
}
return DecalComp;
}
Here is also no pointer check so it again should be created ever.
So crash happens in SetLifeSpan():
void UDecalComponent::SetLifeSpan(const float LifeSpan)
{
if (LifeSpan > 0.f)
{
GetWorld()->GetTimerManager().SetTimer(TimerHandle_DestroyDecalComponent, this, &UDecalComponent::LifeSpanCallback, LifeSpan, false);
}
else
{
GetWorld()->GetTimerManager().ClearTimer(TimerHandle_DestroyDecalComponent);
}
}
As you can see World was never checked to be a non-zero pointer and valid. I think that is why this crash happened, because with some unknown reason world of component where decal wanted to be attached is zero or invalid
UGameplayStatics has also many other functions where pointers not checked to be non-zeroed