LineTraceSingle how to ignore actor C++

Hello, help a newbie understand the basics. In a new project, I created two C++ classes: Cube and MyPawn.

Cube.cpp

// Sets default values
ACube::ACube()
{
 	// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you dont need it.
	PrimaryActorTick.bCanEverTick = true;

	static ConstructorHelpers::FObjectFinder<UStaticMesh>C(TEXT("StaticMesh'/Game/StarterContent/Shapes/Shape_Cube.Shape_Cube'"));
	UStaticMeshComponent* Cube = CreateDefaultSubobject<UStaticMeshComponent>("Cube");
	Cube->SetupAttachment(RootComponent);
	Cube->SetWorldScale3D(FVector(0.1f));
	Cube->SetStaticMesh(C.Object); 
}

MyPawn.cpp

void AMyPawn::BeginPlay()
{
	Super::BeginPlay();

	ACube* MyCube[3];
	ETraceTypeQuery TraceChannel = UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_Visibility);
	const TArray<AActor*> ActorsToIgnore;
	FHitResult HitResult;
	for (int i = 0; i <= 2; i++)
	{
		MyCube[i] = GetWorld()->SpawnActor<ACube>(FVector(0.f + i * 15.f, 150.f, 70.f), FRotator(0.f));
		FVector start = MyCube[i]->GetActorLocation();
		start.Z = 100.f;
		FVector stop = start;
		stop.Z = 0.f;
		UKismetSystemLibrary::LineTraceSingle(GetWorld(), start, stop, TraceChannel, false,
		ActorsToIgnore, EDrawDebugTrace::ForDuration, HitResult, true, FColor::Red, FColor::Green, 500.f);
	}
}

In the end I got this result.

Tell me how I need to correctly write the variable ActorsToIgnore so that the function LineTraceSingle ignores the middle cube?

Your ActorsToIgnore is empty. You either need to spawn the actors up front to an array or during the iteration add the middle element to the ActorsToIgnore array (it can’t be const because it needs to change at runtime)

ACube* MyCube[3];
ETraceTypeQuery TraceChannel = UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_Visibility);
TArray<AActor*> ActorsToIgnore;
FHitResult HitResult;
for (int i = 0; i <= 2; i++)
{
	MyCube[i] = GetWorld()->SpawnActor<ACube>(FVector(0.f + i * 15.f, 150.f, 70.f), FRotator(0.f));

	if (i == 1) {
		ActorsToIgnore.Add(MyCube[i]);
	};

	FVector start = MyCube[i]->GetActorLocation();
	start.Z = 100.f;
	FVector stop = start;
	stop.Z = 0.f;
	UKismetSystemLibrary::LineTraceSingle(GetWorld(), start, stop, TraceChannel, false,
		ActorsToIgnore, EDrawDebugTrace::ForDuration, HitResult, true, FColor::Red, FColor::Green, 500.f);
}

1 Like

Okay, but how can I write into an array cell with
specific index? This code throws an error.

if (i == 1) ActorsToIgnore[0] = MyCube[i];

And a few more questions.
I can write the LineTraceSingle function this way.

Cube.cpp

// Called when the game starts or when spawned
void ACube::BeginPlay()
{
	Super::BeginPlay();
	
	ETraceTypeQuery TraceChannel = UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_Visibility);
	TArray<AActor*> ActorsToIgnore;
	FHitResult HitResult;
	FVector start = GetActorLocation();
	start.Z = 100.f;
	FVector stop = start;
	stop.Z = 0.f;
	UKismetSystemLibrary::LineTraceSingle(GetWorld(), start, stop, TraceChannel, false,
	ActorsToIgnore, EDrawDebugTrace::ForDuration, HitResult, true, FColor::Red, FColor::Green, 500.f);
}

MyPawn.cpp

// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
	Super::BeginPlay();

	ACube* MyCube[3];
	for (int i = 0; i <= 2; i++)
	{
		MyCube[i] = GetWorld()->SpawnActor<ACube>(FVector(0.f + i * 15.f, 150.f, 70.f), FRotator(0.f));
	}
}

How can I ignore all the cubes in this case?
How to ignore only the middle cube?

ActorsToIgnore starts out empty. You cannot just go and reference ActorsToIgnore[0] as that part of the array is not initialized. It probably throws an out of bounds exception right?

valid_index_in_MyCube_array will choose which one of the elements passes through.
0 => first added element
1 => second added element
2 => third added element

ActorsToIgnore.Add(MyCube[valid_index_in_MyCube_array]); on the other hand will expand the ActorsToIgnore array by 1 new element, in this case adding to it and element from the MyCube array.

You can go into arrays blindly, you have to for instance do checks like ActorsToIgnore.Num() to get the amount of elements in the array to see where the upper limit of the array is.

Notice that when you wrote ACube* MyCube[3]; you initialized it with 3 elements. There is no equvalant done for ActorsToIgnore. You could set a predefined limit if you knew up front how many ignores you need, then you could use direct access like [0] , [1], [2] as long as the chosen index is within the arrays length (remember arrays start from 0 so always count -1 with indexes)

1 Like

Thank you friend! You explained everything very well.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.