UPrimitiveComponent does not work in GetComponentsByClass

I am trying to get UPrimitiveComponent components of an Actor in order to calculate the mass of all overlapping actors.
However, the AActor::GetComponentsByClass does not work for me with the UPrimitiveComponent class. It gives an error " does not name a value".

I have tried to search for this, but could not find anything.

UPrimitiveComponent is imported like so:
#include “Runtime/Engine/Classes/Components/PrimitiveComponent.h”

Might this be a language processing error? I am using Rider from JetBrains.

GetComponentsByClass isn’t a template function and as such doesn’t allow you to control what type it returns, it’ll always return TArray<UActorComponent*> and the way you tell it what class to get is by argument as a TSubclassOf so if I’m not mistaken you’d call it like:

TArray<UActorComponent*> PrimitiveComponents = GetComponentsByClass(UPrimitiveComponent::StaticClass())

BUT GetComponentsByClass is deprecated and you should use one of the GetComponents functions instead which you can find the overload list for here.
So it could look something like:

TArray<UPrimitiveComponent*> PrimitiveComponents;
GetComponents<UPrimitiveComponent>(PrimitiveComponents, false /*or true*/);
2 Likes

Thank you very much for the quick response!
Yes, this way it works, thanks again for your help :slight_smile:
And also for showing how to get the StaticClass from a class.

Also I have managed to implement it more or less correctly.
CalculateMassOfComponents is static in the declaration. Not a fan of double traversing, but our DefaultPawn has 2 components, for example. Is doing that with an Iterator a better approach than with higher order functions?

float UDoorOpen::TotalMassOfActors() const
{
	// Find all overlapping actors - is it possible to move this logic to store the actors only once?
	TArray<AActor*> OverlappingActors;
	PressurePlate->GetOverlappingActors(OUT OverlappingActors);
	UE_LOG(LogTemp, Warning, TEXT("Number of overlapping actors: %i"), OverlappingActors.Num());
	
	// Add masses
	float TotalMass = Algo::Accumulate(
		OverlappingActors,
		0.f,
		[](float acc, AActor* el)
		{
			if (el)
			{
				TArray<UPrimitiveComponent*> ActorComponents;
                el->GetComponents<UPrimitiveComponent>(OUT ActorComponents, false);
				UE_LOG(LogTemp, Warning, TEXT("Number of overlapping components: %i"), ActorComponents.Num());
				
				// Unless the function is static, 'this' needs
				// to be captured by the lambda
                return acc + CalculateMassOfComponents(ActorComponents);
			}
			else
				return acc;
		});
	UE_LOG(LogTemp, Warning, TEXT("Calculated mass for overlapping components: %f"), TotalMass);
	
	return TotalMass;
}

float UDoorOpen::CalculateMassOfComponents(const TArray<UPrimitiveComponent*> ActorComponents)
{
	if (ActorComponents.Num() == 0)
		return 0.f;
	if (ActorComponents.Num() == 1)
		// Using CalculateMass instead of GetMass
		// because it is a bit faster
		// If needed to get the precise mass, GetMass is better
		return ActorComponents[0]->CalculateMass();
	return Algo::Accumulate(
		ActorComponents,
		0.f,
		[](float acc, UPrimitiveComponent* el)
		{
			return acc + el->CalculateMass();
		}
	);
}

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

Privacy & Terms