Editor crashes while compiling ONLY IF there is a C++ class inside the level

I’m really not sure what code examples i could give, because as the title says, if i bring any C++ class in a level and hit “Compile” it crashes.

Everything works fine if i put them into the level and click “Play”. They work as intended, but if i compile, it crashes. This means that i have to make a blueprint class of every c++ class that i want to have in my level, as they work with no problem.

I’m not even sure if it’s my fault or the editor is just extremely buggy, but i’m fairly sure that this did not happen from the start.

If this can help, my classes are:

1 C++ GameModeBase -> 3 duplicate blueprint gamemodes derived from it (The number will vary depending on how many levels i’ll make)
1 C++ GameInstance-> 1 Blueprint Gameinstance derived from it
1 C++ Character-> 1 Blueprint character derived from it
1 C++ BoxTrigger-> “N” number of duplicate blueprint classes derived from it

I think this all started happening when i made that BoxTrigger, but somehow it crashes even if i drag the C++ charachter into the level.

GAME INSTANCE HEADER


#pragma once

#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "Action3PGameInstance.generated.h"

UCLASS()
class ACTION3P_API UAction3PGameInstance : public UGameInstance
{
    GENERATED_BODY()

public:
    UAction3PGameInstance();

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Checkpoint")
    int GICheckpointIndex;
};

GAME INSTANCE CPP


#include "Action3PGameInstance.h"

UAction3PGameInstance::UAction3PGameInstance()
{
    GICheckpointIndex = 0;
}

TRIGGERBOX HEADER


#pragma once

#include "CoreMinimal.h"
#include "Engine/TriggerBox.h"
#include "Checkpoint.generated.h"

class APlayerCharacter;

UCLASS()
class ACTION3P_API ACheckpoint : public ATriggerBox
{
    GENERATED_BODY()

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

public:
    // constructor sets default values for this actor's properties
    ACheckpoint();

    // overlap begin function
    UFUNCTION()
    void OnOverlapBegin(class AActor* OverlappedActor, class AActor* OtherActor);

    // overlap end function
    UFUNCTION()
    void OnOverlapEnd(class AActor* OverlappedActor, class AActor* OtherActor);

    UPROPERTY(EditAnywhere, Category = "Checkpoint")
    int CheckpointIndex;
};


TRIGGERBOX CPP


#include "Checkpoint.h"
#include "DrawDebugHelpers.h"
#include "PlayerCharacter.h"
#include "Kismet/GamePlayStatics.h"
#include "Action3PGameInstance.h"
#include "Action3PGameModeBase.h"

ACheckpoint::ACheckpoint()
{
    OnActorBeginOverlap.AddDynamic(this, &ACheckpoint::OnOverlapBegin);
    OnActorEndOverlap.AddDynamic(this, &ACheckpoint::OnOverlapEnd);
}

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

    DrawDebugBox(GetWorld(), GetActorLocation(), GetComponentsBoundingBox().GetExtent(), FColor::Purple, true, 1, 0, 5);
}

void ACheckpoint::OnOverlapBegin(class AActor* OverlappedActor, class AActor* OtherActor)
{
    ACharacter* PlayerRef = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0);
    AAction3PGameModeBase* GameModeRef = (AAction3PGameModeBase*)GetWorld()->GetAuthGameMode();

    if (GameModeRef)
    {
        UAction3PGameInstance* GameInstanceRef = Cast<UAction3PGameInstance>(GameModeRef->GetGameInstance());
        if (PlayerRef != nullptr)
        {
            if (OtherActor && OtherActor == PlayerRef)
            {
                GameInstanceRef->GICheckpointIndex = this->CheckpointIndex;
                UE_LOG(LogTemp, Warning, TEXT("%i %i"), GameInstanceRef->GICheckpointIndex, this->CheckpointIndex);
            }
         }
     }
}

void ACheckpoint::OnOverlapEnd(class AActor* OverlappedActor, class AActor* OtherActor)
{
    ACharacter* PlayerRef = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0);

    if (PlayerRef != nullptr)
    {
        if (OtherActor && OtherActor == PlayerRef)
        {
            UE_LOG(LogTemp, Warning, TEXT("Player Ended Overlap"));
        }
    }
}

Well first things first, never use C Style cast for UObjects. Use the proper UE4 Cast for UObject or templated functions.



AAction3PGameModeBase* GameModeRef = (AAction3PGameModeBase*)GetWorld()->GetAuthGameMode(); 

should either be



AAction3PGameModeBase* GameModePtr = Cast<AAction3PGameModeBase>(GetWorld()->GetAuthGameMode()); 

or



AAction3PGameModeBase* GameModePtr  = GetWorld()->GetAuthGameMode<AAction3PGameModeBase>(); 

Notice Ptr not Ref, as this is a pointer not a reference. (subtle differences between the two in C++).


UPROPERTY(EditAnywhere, Category = "Checkpoint") int CheckpointIndex;

you should strive to use UE4 portability types, so int should be int32.

You should bind your delegates in BeginPlay so move them from constructor to BeginPlay



void ACheckpoint::BeginPlay()
{
    OnActorBeginOverlap.AddDynamic(this, &ACheckpoint::OnOverlapBegin);
    OnActorEndOverlap.AddDynamic(this, &ACheckpoint::OnOverlapEnd);

    Super::BeginPlay();

    DrawDebugBox(GetWorld(), GetActorLocation(), GetComponentsBoundingBox().GetExtent(), FColor::Purple, true, 1, 0, 5);
}


Also try not to use the Compile button in the editor. Always close editor and compile then re-open editor. Live coding can be used but ONLY for changes in function bodies. Not for Constructor/header file changes. HŌRU | Don’t use hot reload in UE4!

1 Like

Hi, thanks for the tips. It’s still crashing via the Compile Button but it seems to be working if i build from VS

Anyway, about the int32 thing, what should i use in blueprints then? In BP there’s only Int and Int64. What’s the BP version of int32?

Int is int32.