BeginOverlap before BeginPlay?

Cheers!

We recently had the following problem:

  • We have a project having a variable being set in BeginPlay
  • This Variable is used in the BeginOverlap Function
  • Starting the game then results in a Crash of the UE4

After we went into it with the debugger,
as it was happening the whole time after that,
we found out that it was a Null Pointer Crash
caused by the Variable in the BeginOverlap Function.

We then, after implementing some checks, put in some
UE_LOG to check what is called first and to our amazement
it was the BeginPlay Function.

Now we would just want to know if this is supposed to happen
and where in the ActorLifecycle
the BeginOverlap is called just so, in case it’s supposed to happen, we know for later.

Hello Higante,

Is this being done in C++ or in Blueprints? Have you tried setting a breakpoint after the variable is set in BeginPlay to ensure that the variable is indeed successfully being set to what you’re intending it to be set to? It could be that the setting of this variable isn’t going through as expected and then the overlap is called and crashes.

If this doesn’t prove fruitful, please provide the code for the declaration of this variable, the two functions, and the definition of the two functions.

We haven’t heard from you in a while, Higante. Are you still experiencing this issue? If so, have you tried what I mentioned in my previous comment? In the meantime, I’ll be marking this issue as resolved for tracking purposes.

I just found this issue too. I put box collision inside BP and spawn Character into this area. Overlap hits before BeginPlay. Is it bug?

I’m sorry for the delay.

It’s written C++. I started the UE4 in Debug per Visual Studio and pressed Play, which shows me that the Variable that I use in BeginOverlap is a nullptr. I’m also sure that BeginOverlap is called before BeginPlay because by printing out a output message, instead of doing the function in BeginOverlap and BeginPlay, it results in the Overlap Function to appear first.

The two Functions we use right now in the .cpp, Parent is set in BeginPlay

BeginPlay:

// Called when the game starts
void URCutting::BeginPlay()
{
	Super::BeginPlay();
	UE_LOG(LogTemp, Warning, TEXT("BeginPlay"));

	// Reference to parent
	Parent = Cast<UStaticMeshComponent>(CutRegion->GetAttachmentRoot());
}

Our Function for BeginOverlap:

void URCutting::StartCut(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
	int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (Parent == nullptr)
	{
		//Parent = Cast<UStaticMeshComponent>(CutRegion->GetAttachmentRoot());
		UE_LOG(LogTemp, Warning, TEXT("BeginOverlap"));
		return;
	}

	FHitResult Hit;
	GetWorld()->LineTraceSingleByProfile(
		Hit,
		CutRegion->GetComponentLocation(),
		Parent->GetForwardVector() * 30,
		FName("BlockAll"));

	if (Hit.bBlockingHit)
	{
		UStaticMeshComponent* Other = (UStaticMeshComponent*) OtherComp;

		bSameTags = false;

		for (FName otherTagname : Other->ComponentTags) {
			if (Parent->ComponentHasTag(otherTagname)) {
				bSameTags = true;
			}
		}

		if (bSameTags || (Other->ComponentHasTag(FName("soft")) && Parent->ComponentHasTag(FName("hard"))) 
			|| Parent->ComponentHasTag(FName("lightsword"))) {

		PosStart = Parent->GetComponentLocation();
		Parent->SetCollisionProfileName(FName("OverlapAll"));
		BlockRegion->SetCollisionProfileName(FName("BlockAll"));

		Parent->BodyInstance.CustomDOFPlaneNormal = Parent->GetForwardVector();
		Parent->SetConstraintMode(EDOFMode::CustomPlane);

		if (Other->GetClass() == UStaticMeshComponent::StaticClass())
		{
			if (Other->GetStaticMesh())
			{
				Other->GetStaticMesh()->bAllowCPUAccess = true;
				Other->SetEnableGravity(false);
				Other->SetSimulatePhysics(false);
				Other->SetCollisionProfileName(FName("NoCollision"));
				Other->ToggleVisibility();
				Other->bGenerateOverlapEvents = false;

				UProceduralMeshComponent* CreatedCuttable = NewObject<UProceduralMeshComponent>(Other);

				CreatedCuttable->ComponentTags.Add(FName("Cuttable"));
				CreatedCuttable->SetRelativeTransform(Other->GetRelativeTransform());
				CreatedCuttable->RegisterComponent();
				CreatedCuttable->SetCollisionProfileName(FName("BlockAll"));
				CreatedCuttable->bUseComplexAsSimpleCollision = false;
				CreatedCuttable->SetEnableGravity(true);
				CreatedCuttable->SetSimulatePhysics(true);
				CreatedCuttable->bGenerateOverlapEvents = true;

				CreatedCuttable->ComponentTags = Other->ComponentTags;

				UKismetProceduralMeshLibrary::CopyProceduralMeshFromStaticMeshComponent(Other, 0, CreatedCuttable, true);
			}
		}
	   }
	}
}

A screenshot from our output:

Thank you for the information, but where is StartCut being bound to the BeginOverlap delegate? Usually, with actors at least, you would have it bound on BeginPlay so none of this would ever happen. Could you please clarify?

StartCut is bound in the constructor.
Don’t you bind it in the contructor?

I’ve personally never bound a delegate in the constructor but that would explain running into this. Keep in mind that BeginPlay cannot be called until everything in a level has loaded, otherwise there would be the risk of there being null references being made due to yet-to-be-loaded assets.

Since the assets need to be loaded before BeginPlay is executed, they’ll be placed in their locations and will trigger and overlap if they do indeed overlap, causing this function to be called before BeginPlay. If this function relies on logic in BeginPlay, it seems only natural to bind it in BeginPlay. Is there a reason it needs to be done in the constructor?

I will try to put it in the BeginPlay function today and will tell you how it worked out, though another project with the same code and declaration works.

So BeginOverlap can be called before BeginPlay?
Doesn’t seem right.

Another thing that perplexes me about your setup; How is this overlap being called this soon in the session? If two assets are already overlapping each other when the game starts, there will be no BeginOverlap calls, as the overlap never really “began” it was just already happening. Is the URCutting asset being spawned at runtime? If so, what is spawning it? What is the URCutting asset? Is it a component of some kind?

The boxes, which have the Overlap functions, are placed before you begin play in the editor. The only thing which spawns is the ProceduralMeshComponent in the Overlap, though that would only happen if there is an overlap with a overlap-generating object. The object it is bind to is also set to not generate Overlap Events.

  • So the URCutting asset is set in the editor and not runtime.
  • The URCutting asset spawns an ProceduralMeshComponent and hides the StaticMeshComponent setting it to not generate Overlap events.
  • The URCutting asset is a SceneComponent, attached to an Actor with StaticMeshComponent(Knife), with three BoxComponents(Handle(blocks), CutCheck and CutRegion(Where the StartOverlap/EndOverlap is)). Those three boxes don’t overlap with each other.

The way I’m understanding this, are you expecting there to be an overlap event called at the beginning of your session, ignoring the order that it’s being called in? You seem to be saying that an overlap event shouldn’t be triggered at all in this scenario.

Could it be that the BeginOverlap is being triggered when the ProceduralMeshComponent is spawned, before the StaticMeshComponent is set to not generate overlap events?

When looking at it in the debugger, have you checked to see what the OverlappedComp and OtherActor are?

I expect and thought that the functions are called in this order:
1.BeginPlay
2.BeginOverlap

  • OverlappedComp is the BoxComponent which has the BeginOverlap in it.

  • OtherComp (we didn’t used OtherActor) is one of our other BoxComponents. Seems like the position hasn’t been saved.

The triggering of ProceduralMeshComponent before StaticMeshComponents generating overlap event is set to false wouldn’t be a problem (except maybe more spawning ProceduralMeshComponents) since we do a check in the EndOverlap, if the object is a ProceduralMeshComponent.
Also we do these settings before generating the Component.

After some more testing I now know that these Overlaps called before BeginPlay just happen when two objects with generate overlap events are together on one actor in my case.
Is that supposed to happen?

Yes, in cases where multiple components on the same actor are causing unwanted overlap or collision responses, you can use custom collision channels to have them ignore each other. If there are multiple instances of this asset in the level and having the collision channels set up that would cause issues, I would check the parent of the two components overlap when BeginOverlap is called to see if you would like to take the action or not.

I believe in this case, since these are components that are doing the overlapping, that the BeginOverlap you’re seeing is being called in the InitializeComponents stage, if we’re going off the Actor Lifecycle documentation.

Ok, I thank you for your help.