返回

扫描多线(通道)检测 | UE4 C++教程

前端

引言

在上一篇教程中,我们介绍了如何使用 SweepSingleByChannel 来检测单个线段的碰撞。在本教程中,我们将介绍如何使用 SweepMultiByChannel 来检测给定半径内的多个线段的碰撞。这对于检测诸如爆炸或子弹等具有范围效果的对象非常有用。

步骤 1:创建一个新的 C++ Actor 类

首先,我们需要创建一个新的 C++ Actor 类来实现我们的扫描功能。右键单击“内容浏览器”中的“内容”文件夹,然后选择“新建”>“C++ 类”>“Actor”。将类命名为“SweepMultiByChannelActor”并单击“创建类”。

步骤 2:添加头文件

接下来,我们需要在头文件中添加一些头文件。打开 SweepMultiByChannelActor.h 并添加以下头文件:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SceneComponent.h"
#include "Components/ShapeComponent.h"
#include "Kismet/GameplayStatics.h"
#include "DrawDebugHelpers.h"

步骤 3:声明变量

接下来,我们需要声明一些变量。在 SweepMultiByChannelActor.h 中添加以下变量:

UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UShapeComponent* ShapeComponent;

UPROPERTY(EditAnywhere, BlueprintReadOnly)
float SweepRadius = 100.0f;

UPROPERTY(EditAnywhere, BlueprintReadOnly)
float SweepLength = 1000.0f;

步骤 4:构造函数

接下来,我们需要在构造函数中初始化我们的变量。在 SweepMultiByChannelActor.cpp 中添加以下构造函数:

ASweepMultiByChannelActor::ASweepMultiByChannelActor()
{
    // Create the shape component
    ShapeComponent = CreateDefaultSubobject<UShapeComponent>(TEXT("ShapeComponent"));

    // Set the shape of the component
    ShapeComponent->SetShape(NewObject<USphereComponent>());

    // Set the size of the component
    ShapeComponent->SetSphereRadius(SweepRadius);

    // Set the location of the component
    ShapeComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));

    // Add the component to the actor
    RootComponent = ShapeComponent;
}

步骤 5:扫描函数

接下来,我们需要创建一个函数来执行扫描。在 SweepMultiByChannelActor.cpp 中添加以下函数:

void ASweepMultiByChannelActor::Sweep()
{
    // Get the world
    UWorld* World = GetWorld();

    // Create the sweep parameters
    FCollisionShape SphereShape = FCollisionShape::MakeSphere(SweepRadius);
    FCollisionQueryParams Params;
    Params.AddIgnoredActor(this);

    // Perform the sweep
    TArray<FHitResult> HitResults;
    World->SweepMultiByChannel(HitResults, ShapeComponent->GetComponentLocation(), ShapeComponent->GetComponentLocation() + FVector(0.0f, 0.0f, SweepLength), SphereShape, ECC_Visibility, Params);

    // Draw the debug lines
    for (const FHitResult& HitResult : HitResults)
    {
        DrawDebugLine(World, ShapeComponent->GetComponentLocation(), HitResult.Location, FColor::Red, false, 1.0f, 0.0f, 1.0f);
    }
}

步骤 6:调用扫描函数

最后,我们需要在某个地方调用扫描函数。您可以将其添加到蓝图事件图中,也可以将其添加到 Tick 函数中。如果您将其添加到蓝图事件图中,则只需创建一个“调用函数”节点并将其连接到“扫描”函数即可。如果您将其添加到 Tick 函数中,则只需在 Tick 函数中添加以下代码即可:

void ASweepMultiByChannelActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    Sweep();
}

结论

现在,您已经创建了一个可以检测给定半径内多个线段的碰撞的 Actor 类。您可以使用此类来检测诸如爆炸或子弹等具有范围效果的对象。