Creating The Wall Spike Class
Inside the C++ Classes ->SideRunner, Right Click -> New C++ Class. Click on the Show All Classes checkbox and filter for spike and select the Spike class as the parent class then click Next:
Open the WallSpike class in Visual Studio and first in the WallSpike.h file declare the constructor, BeginPlay and Tick function:
#include "CoreMinimal.h"
#include "Spikes.h"
#include "WallSpike.generated.h"
/**
*
*/
UCLASS()
class SIDERUNNERCPP_API AWallSpike : public ASpikes
{
GENERATED_BODY()
public:
AWallSpike();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
};
Now let’s implement these functions in the WallSpike.cpp file one by one starting with the constructor:
AWallSpike::AWallSpike()
{
PrimaryActorTick.bCanEverTick = true;
}
void AWallSpike::BeginPlay()
{
Super::BeginPlay();
this->GetRootComponent()->ComponentVelocity = FVector(0, 25, 0);
}
void AWallSpike::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
SetActorLocation(GetActorLocation() + FVector(0, 350 * DeltaTime, 0), true);
}
Again we first calling the same function in the Super class on line 3. On line 4 we set the location of the actor by calling SetActorLocation and passing the current location of the actor with GetActorLocation function and we move it forward by adding the value we set in the FVector variable that we created to the current location of the actor.
This will move the spike wall actor forward and make him chase the player actor. This is the final version of WallSpike.cpp file:
#include "WallSpike.h"
AWallSpike::AWallSpike()
{
PrimaryActorTick.bCanEverTick = true;
}
void AWallSpike::BeginPlay()
{
Super::BeginPlay();
this->GetRootComponent()->ComponentVelocity = FVector(0, 25, 0);
}
void AWallSpike::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
SetActorLocation(GetActorLocation() + FVector(0, 350 * DeltaTime, 0), true);
}
Adding The Wall Spike Obstacle In The Game
Rename the component to Wall, then select it and in the Details tab under Static Mesh select the Cube model for the mesh, and under Materials select BasicShapeMaterial:
The reason why we choose not to detect any collision with the Wall Static Mesh is because we are going to use a Box Collision component to detect the collision with other actors.
So from the Components tab, click on Add Component button and filter for Box Collision:
In the Collision settings for the Wall Collision, set the following options:
void AWallSpike::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
SetActorLocation(GetActorLocation() + FVector(0, 350 * DeltaTime, 0), true);
}
Detecting Collision Between The Player Actor And Game Obstacles
#include "Spike.h"
#include "WallSpike.h"
#include "Engine.h"
void ARunnerCharacter::BeginPlay()
{
Super::BeginPlay();
CanMove = true;
GetCapsuleComponent()->OnComponentBeginOverlap.
AddDynamic(this, &ARunnerCharacter::OnOverlapBegin);
}
In OnOverlapBegin function, we are going to test if the player actor has collided with either the wall or spike obstacle, if that is true, we are going to stop the game, make the player actor invisible, and restart the game after the specified time:
void ARunnerCharacter::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor != nullptr)
{
ASpike* WallSpike = Cast(OtherActor);
ASpike* Spike = Cast(OtherActor);
if (WallSpike || Spike)
{
GetMesh()->Deactivate();
GetMesh()->SetVisibility(false);
CanMove = false;
FTimerHandle UnusedHandle;
GetWorldTimerManager().SetTimer(UnusedHandle, this,
&ARunnerCharacter::RestartLevel, 2.0f, false);
}
}
}
void ARunnerCharacter::RestartLevel()
{
UGameplayStatics::OpenLevel(this, FName(*GetWorld()->GetName()));
}
Every time we collide with the wall or the spike obstacle the player actor disappears from the game, and the level is restarted after 2 seconds as you saw in the preview above.
And with that we have finished our game. Thank you for going through this cool tutorial and sticking until the end, I hope that you had fun learning all of the things we covered as much as I had fun creating this tutorial series.
1 thought on “Create A Side Scroller C++ Game In Unreal Engine Part 4: Detecting Collisions Between Player And Obstacles And Wrapping Up Our Game”
Hi, thank you for your great tutorial! You explains a lot of things in details which truly help to comprehend the meaning of each step.
However, I’m still a bit confused on Wall Spike vs Spike collision.
On BP_Spike, you set the custom collision on Static Mesh component. However, for BP_WallSpike, you create a new Component (Box Collision) to set the custom collision instead of setting the collision directly on the Static Mesh.
Can you help me to understand why?
Thanks before. 🙏