std::call_once isn't called once

Hi guys!

I’m really stuck here with this problem.

You see, I have a AActor class here where I’m trying to use std::call_once inside the constructor. In the editor, I have created a BP based on this class, and I have placed three instances of it. But when I start the game, the procedure that was given to std::call_once isn’t called once. I tried to do something else, created a macro and used atomics to do the same thing, but with no success. What I’m doing wrong here?

here is the class code:


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "FPSCharacter.h"
#include <functional>
#include <mutex>
#include <atomic>
#include "FPSObjectiveActor.generated.h"

typedef std::function<void()> CallbackFunction;
class USphereComponent;
class AFPSCharacter;

class FPSGAME_API AFPSObjectiveActor : public AActor

// Sets default values for this actor's properties


AFPSCharacter* _playerCharacter;
CallbackFunction _callback;

/** <GAMEDEV> Static mesh component */
UPROPERTY(VisibleAnywhere, Category = "Components")
UStaticMeshComponent* _meshComp;

/** <GAMEDEV> Collision component */
UPROPERTY(VisibleAnywhere, Category = "Components")
USphereComponent* _sphereComp;

// <GAMEDEV> Particle system component
UPROPERTY(EditDefaultsOnly, Category = "Effects")
UParticleSystem* _pickUpFX;

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

void PlayEffects(); /

void setCallback(CallbackFunction _cb);

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

// <GAMEDEV> Method used to notify when this actor overlaps another one
virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;



// Fill out your copyright notice in the Description page of Project Settings.

#include "FPSObjectiveActor.h"
#include "Components/StaticMeshComponent.h"
#include "Components/SphereComponent.h"
#include "Kismet/GameplayStatics.h"
#include "FPSCharacter.h"
#include <mutex>
#include <atomic>

//#define CALLBACK_CALLED (]() {static bool is_first_time = true; auto was_first_time = is_first_time; is_first_time = false; return was_first_time; })
#define CALLBACK_CALLED ]()->bool {static std::atomic<bool> first_time(true); return; }

// Sets default values
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;

_meshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp"));
RootComponent = _meshComp;

_sphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
_sphereComp->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);

auto& _tmp = _playerCharacter;
setCallback(&_tmp]() { return _tmp->PrintObjectiveMessage(); });

std::once_flag _wasCallbackExecuted;

[this]() {
auto& _tmp = _playerCharacter;
setCallback(&_tmp]() { return _tmp->PrintObjectiveMessage(); });


//auto& _tmp = _playerCharacter;
//setCallback(&_tmp]() { return _tmp->PrintObjectiveMessage(); });


void AFPSObjectiveActor::PlayEffects()
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), _pickUpFX, GetActorLocation());


void AFPSObjectiveActor::setCallback(CallbackFunction _cb)
_callback = _cb;
UE_LOG(LogTemp, Warning, TEXT("Callback bound"));


// Called when the game starts or when spawned
void AFPSObjectiveActor::BeginPlay()



// Called every frame
void AFPSObjectiveActor::Tick(float DeltaTime)


void AFPSObjectiveActor::NotifyActorBeginOverlap(AActor* _otherActor)

_playerCharacter = Cast<AFPSCharacter>(_otherActor);
if (_playerCharacter) {
_playerCharacter->_bIsCarryingObjective = true;


Here is an image containing the result after using the std::cal:once approach, you can the yellow phrases inside the output window, there are three of them:

And here is an image containing the result after I uncomment the macro and the IF statement:

In both cases, what I’m doing wrong?

Any help will be greatly appreciated!


First of all, as good practice, you should never use anything outside the UE4 C++ API to do gameplay programming in C++, so please do not use std functions.

Second, in Blueprint you have access to the “DoOnce” node that does exactly what you need. So if you have a BP class based on this native C++ class you can do that there in the ActorBeginOverlap BP event.
As for callback I suggest you to use UE4 delegates

Thanks for your reply! I’ll modify the code and then i’ll update this thread later =)