Download

Unreal Engine 4.25 crash after calling Destroy() func of an actor

I have two classes:


ATestProjectCharacter

and


AMyEnemy

.
The in the Character class I have the following function:


void ATestProjectCharacter::OnFire()
{ UWorld* const World = GetWorld();
  if (World != NULL)
  {
  [INDENT=2]FHitResult OutHit;[/INDENT]
  [INDENT=2]FCollisionQueryParams CollisionParams;[/INDENT]
  [INDENT=2]World->LineTraceSingleByChannel(OutHit, FirstPersonCameraComponent->GetComponentLocation(), (FirstPersonCameraComponent->GetForwardVector() * 100000.f) + FirstPersonCameraComponent->GetComponentLocation(), ECC_Visibility);[/INDENT]
  [INDENT=2]if (OutHit.bBlockingHit)[/INDENT]
  [INDENT=2]{[/INDENT]
  [INDENT=3]if (AMyEnemy* Enemy = Cast<AMyEnemy>(OutHit.GetActor()))[/INDENT]
  [INDENT=3]{[/INDENT]
  [INDENT=4]Enemy->Destroy();[/INDENT]
  [INDENT=3]}[/INDENT]
  [INDENT=3]if (GEngine)[/INDENT]
  [INDENT=3]{[/INDENT]
  [INDENT=4]GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("You are hitting: %s"), *OutHit.GetActor()->GetName()));[/INDENT]
  [INDENT=4]GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("Impact Point: %s"), *OutHit.ImpactPoint.ToString()));[/INDENT]
  [INDENT=4]GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("Normal Point: %s"), *OutHit.ImpactNormal.ToString()));[/INDENT]
  [INDENT=3]}[/INDENT]
  [INDENT=2]}[/INDENT]
  }
 

 }

Here are my Enemy class declaration:


UCLASS()
class TESTPROJECT_API AMyEnemy : public AActor
{ GENERATED_BODY()
 

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

private: UPROPERTY(VisibleAnywhere, Category = Mesh)
  class UStaticMeshComponent* VisualMesh;
 

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

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

};

and constructor:


AMyEnemy::AMyEnemy()
{ // 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;
    static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeStaticMesh(TEXT("/Game/Geometry/Meshes/1M_Cube"));
    VisualMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
  VisualMesh->SetStaticMesh(CubeStaticMesh.Object);
  VisualMesh->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);
  VisualMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
    RootComponent = VisualMesh;
 

}

So when in-game I call the OnFire() function the game works *until *I shoot the AMyEnemy class. After that my Engine crashes with the following error:


LoginId:1e57549641bc013bdb2c9986df14a710
EpicAccountId:e201a9adcd7443119e9ebb152ebc1ccd

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x00000018

UE4Editor_TestProject_2396!ATestProjectCharacter::OnFire() [C:\Users\Kasless\Documents\Unreal Projects\TestProject\Source\TestProject\TestProjectCharacter.cpp:116]
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Core
UE4Editor_Core
UE4Editor_Core
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_UnrealEd
UE4Editor_UnrealEd
UE4Editor
UE4Editor
UE4Editor
UE4Editor
UE4Editor
kernel32
ntdll

I *tried *to search for that error but I failed.
If you need any forward information ask me and I’ll attach it obviously.

if !Enemy->IsPendingKill()
Enemy->Destroy()

Recoded the function and it still crashes:









void ATestProjectCharacter::OnFire()
{ UWorld* const World = GetWorld();
  if (World != NULL)
  {
  [INDENT=2]FHitResult OutHit;[/INDENT]
  [INDENT=2]FCollisionQueryParams CollisionParams;[/INDENT]
  [INDENT=2]World->LineTraceSingleByChannel(OutHit,[/INDENT]
  [INDENT=7]FirstPersonCameraComponent->GetComponentLocation(),[/INDENT]
  [INDENT=7](FirstPersonCameraComponent->GetForwardVector() * 100000.f) + FirstPersonCameraComponent->GetComponentLocation(),[/INDENT]
  [INDENT=7]ECC_Visibility);[/INDENT]
  [INDENT=2]if (OutHit.bBlockingHit)[/INDENT]
  [INDENT=2]{[/INDENT]
  [INDENT=3]if (AMyEnemy* Enemy = Cast<AMyEnemy>(OutHit.GetActor()))[/INDENT]
  [INDENT=3]{[/INDENT]
  [INDENT=4]if(!Enemy->IsPendingKill())[/INDENT]
  [INDENT=4]{[/INDENT]
  [INDENT=5]Enemy->Destroy();[/INDENT]
  [INDENT=4]}[/INDENT]
  [INDENT=3]}[/INDENT]
  [INDENT=3]if (GEngine)[/INDENT]
  [INDENT=3]{[/INDENT]
  [INDENT=4]GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("You are hitting: %s"), *OutHit.GetActor()->GetName()));[/INDENT]
  [INDENT=4]GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("Impact Point: %s"), *OutHit.ImpactPoint.ToString()));[/INDENT]
  [INDENT=4]GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("Normal Point: %s"), *OutHit.ImpactNormal.ToString()));[/INDENT]
  [INDENT=3]}[/INDENT]
  [INDENT=2]}[/INDENT]
  }
 


 }









Maybe I did something wrong?

UPD: If I code this:









if (AMyEnemy* Enemy = Cast<AMyEnemy>(OutHit.GetActor())) { if(Enemy->IsPendingKill())
  {
  [INDENT=2]Enemy->Destroy();[/INDENT]
  }
 

 }







Enemy is not going to be destroyed(

it needs to be !Enemy->IsPendingKill()

In your original code, you were trying to print the actors name after you destroyed the actor, this will make the game crash.


GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("You are hitting: %s"), *OutHit.GetActor()->GetName()));

Once you call destroy on the actor, you cannot access anything from that actor at that point in time in the code.

In the future, if you want to print that debug line, it must go before the destroy call.

Thanks for explaining :3