Collider Overlaps in UE4 cpp (C++)
Here we’ll cover how to sign onto events that check for collision overlaps in UE4, and check for collision manually. It seems like it should be incredibly straight forward for a newcomer, but it actually isn’t so crystal clear as it might seem.
!IF YOU WANT TO JUMP RIGHT TO THE COLLISION, CLICK HERE!
The UShapeComponent
First we’re going to need our collision component, these are the bounds that will actually be checking for collision and you can see in the Unreal world editor and blueprint editor. The main ones that people use for collision detection are derived from the UShapeComponent, which, as the documentation states, “is a PrimitiveComponent that is represented by a simple geometrical shape (sphere, capsule, box, etc).”
And as it says you will mostly be using the UBoxComponent, UCapsuleComponent, and USphereComponent. These all work very similarly, mostly just overriding the base UShapeComponent functionality, with special handling to better represent the data specific to their shape type. Since all of these shapes are so similar, we’ll only look at one of these components, as they more-or-less function the same.
Creating our UBoxComponent
First we need to add a reference to our UBoxComponent, instantiate it and set it up in our default constructor. To do so, we’ll need to make sure to add the UBoxComponent’s include file to the top of our header file as so.
#include "Components/BoxComponent.h"
You can see the include file, as well as any module it resides in on the unreal documentation, you should always have these pages pulled up when working with an unfamiliar component, or learning about an object’s API. You can find the documentation for UBoxComponent here.
Next, inside of our AActor class, we need to setup a class* reference to our box component. This is going to hold the reference to the component that we will be instantiating in the constructor. You can declare yours as such:
//Components private: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess=true)) class UBoxComponent* Collider;
Next we will need to create it in the constructor, if you do not have one, in your public section create a function that matches the same name as your AActor class name, in my case, my class is titled “ATestCollider”
public: ATestCollider();
Next, we’ll want to implement our default constructor and create and initialize the UBoxComponent.
ATestCollider::ATestCollider()
{
PrimaryActorTick.bCanEverTick = false;
Collider = CreateDefaultSubobject(TEXT("Collider"));
Collider->SetupAttachment(RootComponent, NAME_None);
Collider->SetGenerateOverlapEvents(true);
Collider->SetBoxExtent(FVector(100.f, 100.f, 100.f), false);
Collider->SetCollisionProfileName(TEXT("Trigger"), false);
}
Line by line we’ll go through the constructor:
1. We are setting the Actor to not tick, this is typical to any AActor that you don’t want executing every frame.
2. Here we are instantiating the UBoxComponent, and giving it a subobject name of “Collider” we are setting our Collider pointer to reference this object.
3. If you think about the structure of your Blueprint, there is a hierarchy just like the world outliner. Here, we are determining where in that Blueprint outliner the Collider object sits, for my purposes, I just want it sitting right underneath the root component of the Blueprint. Every AActor has a RootComponent that is there by default.
4. In order to recieve overlap events, we need to make sure that Unreal knows that we want them! If we didn’t Unreal wouldn’t want to waste time processing them. Make sure to set this to true on your player as well.
5. Here we are just setting the size of the box extents, we are using 100 for each axis to get a uniform 1-meter cube.
6. Here we are setting the Collision Profile in the Physics settings. This will make sure that we have specific physics settings, and won’t be blocking the player, but merely triggering an interaction with them.
With that, if you compile your code, and open up Unreal, you should be able to drag in your TestCollider from the C++ files section of the Content Browser.
You can hopefully see the UBoxComponent outlines, and ensure it has the proper hierarchy.
The Collision
For the collision, you need to do two things, you need to first implement the OnComponentOverlap function. The second thing is that we tell the UBoxComponent to call this function with the matching signature when it detects an overlap.
First we’ll implement the OnComponentOverlap function, and we’ll have it simply output a message to the screen when it detects an overlap, to make sure our function is working.
void ATestCollider::OnComponentOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.f, FColor::Red, *FString::Printf(TEXT("On Component Overlap Begin!"))); }
The “GEngine->AddOnScreenDebugMessage” is the equivelant to the blueprint function “PrintString” (NOTE: Make sure when creating the function definition in the headerfile, you supply the UFUNCTION() property to the function, to the reflection system can find the function and serialize it properly for binding in the next step.
Next we have to tell our Collider to call this function when it detects an overlap. Personally, I like to do this binding in BeginPlay, as opposed to the constructor. The reason for this, is that the constructor is only called at specific moments, and when the game is created, it is only called once at start to get the class base that all future instantiations are based off of. In the editor, I have frequently ran into issues when Hot-Reloading code that lives inside of the constructor. Anyway here is the code to bind the function:
Collider->OnComponentBeginOverlap.AddDynamic(this, &ATestCollider::OnComponentOverlap);
We use the AddDynamic UE macro to bind the UObject instance to our UFUNCTION that we created for when something overlaps with our collider.
Testing
Now, you should be able to compile your code, and walk right through your collider box, and get a message on-screen! You might want to drop in a static mesh next to your trigger so that you know where to walk, or even add another component to your trigger actor.
Errors
If you are running into issues, make sure that you are not colliding and being blocked by your trigger, make sure that your code is compiled properly, try closing and reopening the engine to make sure Hot-Reloading didn’t go wrong, and make sure that your OnComponentOverlap implementation is marked as a UFUNCTION(). Make sure that the Trigger Box, as well as your player have the setting GenerateOverlapEvents set to true, otherwise these events will not be generated and not fire.
Other Overlap Functions
Now that you did OnComponentOverlap, you can do other’s as well! If you read through the documentation you can see what else is out there, for instance, OnComponentBeginOverlap lives inside of the UPrimitiveComponent class. Another function that would be important is OnComponentEndOverlap. Why don’t you try implementing that as well? You can have a look at UPrimitiveComponent here.