Beginner question: Bind events in constructor (or BeginPlay) not updating blueprint when modified

I’m following a basic tutorial to get started with UE4. However, it’s blueprint based and I’m wanting to learn both BP and C++ approach at the same time. I’m not worried about the coding aspect of C++, although I’m getting hung up on some engine specific nuances.

One thing that I currently can’t wrap my head around is what to do when a C++ class binds events, and then a BP is created based off of that class. Initially, I was putting my bindings in the constructor, but I read Delegate invocation list changes inside a constructor does not propagate to a derived blueprint. - C++ Gameplay Programming - Unreal Engine Forums and tried to move it to the BeginPlay. It looks like this now:



void ACPP_Banana::BeginPlay()
{
    Super::BeginPlay();

    Mesh->OnComponentBeginOverlap.AddDynamic(this, &ACPP_Banana::OnOverlapBegin);
}

void ACPP_Banana::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
    Destroy();
}


This works great for a blueprint created off of it. However, let’s say that I want to no longer have this class handle overlaps, so I comment out the AddDynamic line. When I do this, and rebuild everything, the overlap still fires and causes a destruction. If I create a new blueprint off of it, there won’t be a collision.

How do people approach this problem in general? I ran into a similar issue for my Pawn class regarding a default collision profile. I can’t imagine a project is supposed to recreate blueprints then replace references for every c++ update.

I’m thinking that I may need to combine RemoveDynamic and AddDynamic to prevent caching of the subscription by the Blueprint component. Is this accurate, or am I missing something?

I don’t know the details, but hot reload is not 100% accurate. Sometimes you need to recompile the modified BP, or even restart the editor to see the update.
I lost countless time trying to fix “bugs”, while restarting the editor was just the solution…
Did you try it?

yeah hot reload doesnt always get it the 1st attempt. sometimes you have to compile 2x in a row. sometimes you have to delete the blueprint from the viewport and place it back in also depending on what you changed in the blueprint. sometimes you have to restart the editor.

blueprints get serialized and when you modify them too much it can break the blueprint. sometimes the editor is able to properly update the blueprint othertimes not so much.

Hm. I have tried this but I must be doing something wrong. I am just X’ing out of the editor (project fully close). Does anything stay open that needs killed further?

I just tried again with this class:



#include "CPP_Banana.h"

// Sets default values
ACPP_Banana::ACPP_Banana()
{
     // 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;

    Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
    RootComponent = Mesh;
    Mesh->SetCollisionProfileName("OverlapOnlyPawn");

    RotationSpeed = 100.0;
}

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

    //Mesh->OnComponentBeginOverlap.RemoveDynamic(this, &ACPP_Banana::OnOverlapBegin);
    Mesh->OnComponentBeginOverlap.AddDynamic(this, &ACPP_Banana::OnOverlapBegin);
}

// Called every frame
void ACPP_Banana::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    FRotator rotation = FRotator(0.0, RotationSpeed * DeltaTime, 0.0);
    FQuat QuatRotation = FQuat(rotation);
    AddActorLocalRotation(QuatRotation);
}

void ACPP_Banana::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
    Destroy();
}


I have the blueprint and added it to the view. Everything works great. I then comment out the AddDynamic line, hit play, and it…still works great. This is unexpected because it’s not bound. I uncomment the RemoveDynamic (add is still commented) and it no longer collides (expected).

I tried to restart the editor after commenting out the AddDynamic line and it still was colliding.

I copy pasted the blueprint and moved it to a different location in the view (2 instances now). I moved onto the new blueprint and…the old one was destroyed.

My understanding of how the blueprint instances work is clearly way out of whack. Any reading material or explanation is appreciated.

Edit: Thank you both for the comments / help so far, btw :smiley: