The original tutorial is based on UE 4.18, I am based on UE 4.25.

English original Address

In a very interesting tutorial, we will simulate explosions by adding radial thrust to all objects within a set range.

Create a new role named AddRadialForce. We don’t need to do anything with the header file. Below is the default header generated by Unreal.

AddRadialForce.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "AddRadialForce.generated.h"

UCLASS(a)class UNREALCPP_API AAddRadialForce : public AActor
{
	GENERATED_BODY(a)public:	
	// Sets default values for this actor's properties
	AAddRadialForce(a);protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay(a) override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
	
};
Copy the code

To help with debugging, let’s add the DrawDebugHelpers header file to our code.

#include "AddRadialForce.h"
// add debug helpfers
#include "DrawDebugHelpers.h"
Copy the code

In this example, we will perform all the logic in the BeginPlay() function. We want to collect all the hit results in our scope and get the results from the scan of the scope. To do this, we’ll use TArray to track overlapping actors.

void AAddRadialForce::BeginPlay(a)
{
	Super::BeginPlay(a);// create tarray for hit results
	TArray<FHitResult> OutHits;

	// crate tarray for sweep actors
	TArray<AActor*> SweepActors;
	
}
Copy the code

Next we declare the TArray array OutHits. We want the scan range to start and end at the actor’s position and make the CollisionShape a 500 unit sphere. You can get the location of the actor using GetActorLocation(), which returns a vector. We use FCollisionShape:: Makephere (500.0f) to create a CollisionShape.

// Called when the game starts or when spawned
void AAddRadialForce::BeginPlay(a)
{
	Super::BeginPlay(a);// create tarray for hit results
	TArray<FHitResult> OutHits;

	// get actor locations
	FVector MyLocation = GetActorLocation(a);// start and end locations. The sphere will create the radial sweep.
	FVector Start = MyLocation;
	FVector End = MyLocation;

	// create a collision sphere
	FCollisionShape MyColSphere = FCollisionShape::MakeSphere(500.0 f);
	
}
Copy the code

To visualize the scanned sphere, we will draw a debug sphere.

// Called when the game starts or when spawned
void AAddRadialForce::BeginPlay(a)
{
	Super::BeginPlay(a);// create tarray for hit results
	TArray<FHitResult> OutHits;

	// get actor locations
	FVector MyLocation = GetActorLocation(a);// start and end locations. The sphere will create the radial sweep.
	FVector Start = MyLocation;
	FVector End = MyLocation;

	// create a collision sphere
	FCollisionShape MyColSphere = FCollisionShape::MakeSphere(500.0 f);

	// draw collision sphere
    DrawDebugSphere(GetWorld(), GetActorLocation(), MyColSphere.GetSphereRadius(), 50, FColor::Cyan, true);
}
Copy the code

Next we check to see if our actor hit anything when we BeginPlay(). Each actor has a GetWorld function. From, we’ll use the SweepMultiByChannel() function from the GetWorld() function and set it to the variable just created above as an argument. This returns a bool indicating whether there are other actors in the scope of this actor.

void AAddRadialForce::BeginPlay(a)
{
	Super::BeginPlay(a);// create tarray for hit results
	TArray<FHitResult> OutHits;

	// get actor locations
	FVector MyLocation = GetActorLocation(a);// start and end locations. The sphere will create the radial sweep.
	FVector Start = MyLocation;
	FVector End = MyLocation;

	// create a collision sphere
	FCollisionShape MyColSphere = FCollisionShape::MakeSphere(500.0 f);

	// draw collision sphere
	DrawDebugSphere(GetWorld(), GetActorLocation(), MyColSphere.GetSphereRadius(), 50, FColor::Cyan, true);
	
	// check if something got hit in the sweep
	bool isHit = GetWorld() - >SweepMultiByChannel(OutHits, Start, End, FQuat::Identity, ECC_WorldStatic, MyColSphere);
	
}
Copy the code

If isHit is true, we will add radial thrust to the root component of each successfully cast actor by iterating over a number of OutHits.

if (isHit)
	{
		// loop through TArray
		for (auto& Hit : OutHits)
		{
			UStaticMeshComponent* MeshComp = Cast<UStaticMeshComponent>((Hit.GetActor() - >GetRootComponent());

			if (MeshComp)
			{
                // alternivly you can use ERadialImpulseFalloff::RIF_Linear for the impulse to get linearly weaker as it gets further from origin.
				// set the float radius to 500 and the float strength to 2000.
				MeshComp->AddRadialImpulse(GetActorLocation(), 500.f.2000.f, ERadialImpulseFalloff::RIF_Constant, true); }}}Copy the code

The final complete CPP code is shown below

#include "AddRadialForce.h"
// add debug helpfers
#include "DrawDebugHelpers.h"

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

}

// Called when the game starts or when spawned
void AAddRadialForce::BeginPlay(a)
{
	Super::BeginPlay(a);// create tarray for hit results
	TArray<FHitResult> OutHits;

	// get actor locations
	FVector MyLocation = GetActorLocation(a);// start and end locations. The sphere will create the radial sweep.
	FVector Start = MyLocation;
	FVector End = MyLocation;

	// create a collision sphere
	FCollisionShape MyColSphere = FCollisionShape::MakeSphere(500.0 f);

	// draw collision sphere
	DrawDebugSphere(GetWorld(), GetActorLocation(), MyColSphere.GetSphereRadius(), 50, FColor::Cyan, true);
	
	// check if something got hit in the sweep
	bool isHit = GetWorld() - >SweepMultiByChannel(OutHits, Start, End, FQuat::Identity, ECC_WorldStatic, MyColSphere);

	if (isHit)
	{
		// loop through TArray
		for (auto& Hit : OutHits)
		{
			UStaticMeshComponent* MeshComp = Cast<UStaticMeshComponent>((Hit.GetActor() - >GetRootComponent());

			if (MeshComp)
			{
				// alternivly you can use ERadialImpulseFalloff::RIF_Linear for the impulse to get linearly weaker as it gets further from origin.
				// set the float radius to 500 and the float strength to 2000.
				MeshComp->AddRadialImpulse(GetActorLocation(), 500.f.2000.f, ERadialImpulseFalloff::RIF_Constant, true); }}}}// Called every frame
void AAddRadialForce::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}
Copy the code

The actual operation of the renderings below

\