射线检测简单来说就是通过相机发射一条射线,用来检测对象的一种检测机制。
官网介绍:使用射线进行命中判定
这里主要介绍4种常用的射线检测方式。
关键API:LineTraceSingleByChannel
声明变量
MyCharacter.h
//射线检测
FVector StartLocation;
FVector EndLocation;
FVector Direction;
FHitResult HitResult;
在Tick中实现通道进行射线检测
MyCharacter.cpp
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
StartLocation = MyCamera->GetComponentLocation();
Direction = MyCamera->GetForwardVector();
EndLocation = StartLocation + Direction * 1000.f;
// 根据通道进行射线检测
bool bHit = GetWorld()->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECC_Visibility); // 根据通道查询检测
if (bHit)
{
AActor *HitActor = HitResult.GetActor();
FVector ImpactPoint = HitResult.ImpactPoint;
FVector HitLocation = HitResult.Location;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("HitActor 1 :%s"), *HitActor->GetName()));
}
}
编译 之后,在场景中添加CUBE运行
关键API:LineTraceSingleByObjectType
声明变量
MyCharacter.h
//射线检测
FVector StartLocation;
FVector EndLocation;
FVector Direction;
FHitResult HitResult;
在Tick中实现通道进行射线检测
MyCharacter.cpp
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
StartLocation = MyCamera->GetComponentLocation();
Direction = MyCamera->GetForwardVector();
EndLocation = StartLocation + Direction * 1000.f;
// 根据对象查询检测
//添加通道 按指定对象检测,非指定指定对象是不会检测到的
FCollisionObjectQueryParams ObjectQueryParams;
ObjectQueryParams.AddObjectTypesToQuery(ECC_WorldStatic);
bool bHit2 = GetWorld()->LineTraceSingleByObjectType(HitResult, StartLocation, EndLocation, ObjectQueryParams); // 根据对象查询检测
if(bHit2)
{
AActor *HitActor = HitResult.GetActor();
FVector ImpactPoint = HitResult.ImpactPoint;
FVector HitLocation = HitResult.Location;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("HitActor 2 :%s"), *HitActor->GetName()));
}
}
编译 之后,在场景中添加CUBE运行
关键API:LineTraceMultiByChannel
声明变量
MyCharacter.h
//射线检测
FVector StartLocation;
FVector EndLocation;
FVector Direction;
FHitResult HitResult;
//多射线检测
TArray<FHitResult> HitResults;
在Tick中实现通道进行射线检测
MyCharacter.cpp
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
StartLocation = MyCamera->GetComponentLocation();
Direction = MyCamera->GetForwardVector();
EndLocation = StartLocation + Direction * 1000.f;
// 根据多通道进行射线检测
bool HitMuilt= GetWorld()->LineTraceMultiByChannel(HitResults, StartLocation, EndLocation, ECC_Visibility); // 多射线检测
if (HitMuilt)
{
for (int32 i = 0; i < HitResults.Num(); i++)
{
AActor *HitActor = HitResults[i].GetActor();
FVector ImpactPoint = HitResults[i].ImpactPoint;
FVector HitLocation = HitResults[i].Location;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("HitActor 3 :%s"), *HitActor->GetName()));
}
}
}
编译 之后,在场景中添加CUBE运行。
关键API:LineTraceMultiByObjectType
声明变量
MyCharacter.h
//射线检测
FVector StartLocation;
FVector EndLocation;
FVector Direction;
FHitResult HitResult;
//多射线检测
TArray<FHitResult> HitResults;
在Tick中实现通道进行射线检测
MyCharacter.cpp
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
StartLocation = MyCamera->GetComponentLocation();
Direction = MyCamera->GetForwardVector();
EndLocation = StartLocation + Direction * 1000.f;
// 多射线对象查询检测
FCollisionObjectQueryParams ObjectQueryParams;
ObjectQueryParams.AddObjectTypesToQuery(ECC_WorldStatic);
ObjectQueryParams.AddObjectTypesToQuery(ECC_WorldDynamic);
bool HitMuilt2 = GetWorld()->LineTraceMultiByObjectType(HitResults, StartLocation, EndLocation, ObjectQueryParams); // 多射线检测
if (HitMuilt2)
{
for (int32 i = 0; i < HitResults.Num(); i++)
{
AActor *HitActor = HitResults[i].GetActor();
FVector ImpactPoint = HitResults[i].ImpactPoint;
FVector HitLocation = HitResults[i].Location;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("HitActor 4 :%s"), *HitActor->GetName()));
}
}
}
编译之后,要把CUBE设置为ECC_WorldDynamic 类型碰撞
在场景中运行,也是能正常打印的。