The original tutorial is based on UE 4.18, I based on UE 4.25.
English original address
Follow up with a tutorial that shows how to use SweepMultiByChannel to return results within a given radius.
Create a new C++ Actor subclass and name it MySweepActor. We won’t make any changes to the default header file.
Here is the final header file.
MySweepActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MySweepActor.generated.h"
UCLASS(a)class UNREALCPP_API AMySweepActor : public AActor
{
GENERATED_BODY(a)public:
// Sets default values for this actor's properties
AMySweepActor(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
Before we can write the logic of the code, we must first use the #include drawdebughelpers.h file to help us visualize actors.
#include "MySweepActor.h"
// include debug helpers
#include "DrawDebugHelpers.h"
Copy the code
In this example, we will perform all the logic in the BeginPlay() function.
First, we’ll create a TArray of FHitResults and name it OutHits.
We want the scanned sphere to start and end at the same location, and to be equal to the actor’s location by using GetActorLocation. Collision spheres can be of different shapes. In this example, we will use FCollisionShape:: makephere to make it a sphere. We will set its radius to 500 unreal units. Next, run DrawDebugSphere to visually scan the spheres.
Then, we want to set a bool variable called isHit to check if our scan hit anything.
We run GetWorld()->SweepMultiByChannel to perform the scan channel trace and return the hit to the OutHits array.
You can learn more about the SweepMultiByChannel feature here. If isHit is true, we will loop through the TArray and print out the name of the hit actor and other relevant information.
You can learn more about TArray here.
Below is the final.cpp file.
MySweepActor.cpp
#include "MySweepActor.h"
#include "DrawDebugHelpers.h"
// Sets default values
AMySweepActor::AMySweepActor()
{
// 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 AMySweepActor::BeginPlay(a)
{
Super::BeginPlay(a);// create tarray for hit results
TArray<FHitResult> OutHits;
// start and end locations
FVector SweepStart = GetActorLocation(a); FVector SweepEnd =GetActorLocation(a);// create a collision sphere
FCollisionShape MyColSphere = FCollisionShape::MakeSphere(500.0 f);
// draw collision sphere
DrawDebugSphere(GetWorld(), GetActorLocation(), MyColSphere.GetSphereRadius(), 50, FColor::Purple, true);
// check if something got hit in the sweep
bool isHit = GetWorld() - >SweepMultiByChannel(OutHits, SweepStart, SweepEnd, FQuat::Identity, ECC_WorldStatic, MyColSphere);
if (isHit)
{
// loop through TArray
for (auto& Hit : OutHits)
{
if (GEngine)
{
// screen log information on what was hit
GEngine->AddOnScreenDebugMessage(- 1.5.f, FColor::Green, FString::Printf(TEXT("Hit Result: %s"), *Hit.Actor->GetName()));
// uncommnet to see more info on sweeped actor
// GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("All Hit Information: %s"), *Hit.ToString()));}}}}// Called every frame
void AMySweepActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Copy the code
The final run looks like this