Download

[C++]Getting Components from BluePrint using C++

Hello dear community.I’ve been struggling lately on how to query components of an Actor which created with C++ and Blueprint.
In detail : I have a simple Actor class which only has a CollisionComponent.Then I’m adding a static Mesh component from Blueprint which I create from the editor by selecting Custom classes when creating.My goal is to get this StaticMeshComponent and change its material during runtime.I’ve tried several things which ended up failure.I know there’s a function which returns a TArray<UActorComponent> but I couldnt find a way to use it.Can anyone lead the way?

Notes:
I’ve tried setting the static mesh from C++ but that’s not what I want.
When trying to get Actor components,I dont cast the Actor to my individual actor class because it’s not the blueprint one.In fact,I get my blueprint edited Actor from Line Trace during runtime.

It doesnt matter if its static mesh component or not,I need to be able get information of what an Actor’s components during run time.

**EDIT: SOLVED **

I’ve digged around and finally found the solution.Here’s the code with comments


AActor* hitActor = hitRes.GetActor();
		if( hitActor )
		{
			if( redMat )
			{

				UMaterialInstanceDynamic* redMatDynamic = UMaterialInstanceDynamic::Create(redMat,this);
				TArray<UActorComponent*> comps;

				hitActor->GetComponents( comps );
				for( int i=0; i < comps.Num(); ++i ) //Because there may be more components
				{
					UStaticMeshComponent* thisComp = Cast<UStaticMeshComponent>(comps*); //try to cast to static mesh component
					if( thisComp )
					{
						//This is the static mesh component

						thisComp->SetMaterial(0,redMatDynamic);
						uIntersectedActorSMC = thisComp;
						isGraySet = false;

					}
				}
			}
		}


I had the same issue and although there may be a better approach, this was mine, and it worked :slight_smile:

https://answers.unrealengine.com/questions/22865/static-mesh-from-blueprint.html

I basically used the StaticMeshActor when creating my C++ class (Add code to project->Choose StaticMeshActor class instead of base Actor class). This will allow you to have access to the StaticMeshComponent->SetMaterial function which I’m assuming your looking for. I also had the same trouble with the GetComponents array and got lost in trying to use it. Hope this helps somehow.

Hey,thanks for answer.I just got it working with querying all components as I wanted.I will post the code soon!

As a side note - AActor::GetComponents templated on a component type. In case you need only one type of components you can write a much shorter version of your code:


	
TArray<UStaticMeshComponent*> comps;

hitActor->GetComponents(comps);
for (auto StaticMeshComponent : comps)
{
	StaticMeshComponent->SetMaterial(0, redMatDynamic);
	uIntersectedActorSMC = StaticMeshComponent;
	isGraySet = false;
}


Thanks for the tip ddvlost!

using this as a reference, but im using it slightly wrong and could use a hand.

Im trying to do the same, and return a custom class AModuleConnector.
AModuleConnector is a class with nothing in it but the unreal engine generated code.
AModuleConnector : public AActor
and Module is also a custom class.

Thanks for your help!



TArray<AModuleConnector*> AModule::GetExits()
{
	TArray<AModuleConnector*> comps;
	this->GetComponents(comps);

	for (auto ModuleConnector : comps)
	{
		//Do something here to them if needs be.
	}

	return comps;
}


You should use ActorIterator to find all actors of specific class, like this:


TArray<AModuleConnector*> AModule::GetExits()
{
	TArray<AModuleConnector*> ModuleConnectors;
	for (TActorIterator<AModuleConnector> It(GetWorld()); It; ++It)
	{
		AModuleConnector* ModuleConnector = *It;
		//Do something here to them if needs be.
		ModuleConnectors.Add(ModuleConnector);
	}
	return ModuleConnectors;
}

Or probably AModuleConnector should be a component instead of actor, then you can use GetComponents() function

Ah i misunderstood the relationship between an Actor and a component.
So a Component is a element of an Actor. that much makes sense to me;
What im trying to do is find all the child actors (of this class) inside an actor.

Would the best way to do this be to iterate through all the actors in the world and check if its parent is the AModule parent???

How would i go about making the Class a Component instead of a actor, as this seems conceptually to make more sense,

Im trying to create this, if you have a moment i think it will make my question much more clear.

All the logic is there, just having some problems with Syntax.

Thanks ddvlost.

If you are asking to find all Actor instances of a particular class in the World, you can use something like this (taken from GameMode):



for (TActorIterator<APlayerStart> It(World); It; ++It)
{
	APlayerStart* Start = *It;
	if (Start && Start->PlayerStartTag == FName(*IncomingName))
	{
		return Start;
	}
}


This should be pretty quick, we keep a map of class to instances of that class.

Thanks JamesG for your reply, i had thought this might be a workaround but it would not be ideal (unless i misunderstood, but that will call every AModuleConnector)
I only wish to find the AModuleConnector Actors of a specific Module piece.

Module.jpg
A = AModule (Custom blueprint made under Module class) , B = ChildActor with AModuleConnector , C = ChildActor with AModuleConnector

Here is the AModule Components Blueprint. When the member function of AModule FindExits() is called i need it to return a TArray with B and C (or if there is more AModuleConnectors those as well) inside of it.

Additionally, is a Child Actor (selected from add component in the BP editor) both an actor and a component?
Thanks!

Edit:


TArray<AModuleConnector*> AModule::GetExits()
{
	TArray<AModuleConnector*> comps;
	UWorld* const World = GetWorld();
	for (TActorIterator<AModuleConnector> It(World); It; ++It)
	{
		AModuleConnector* ModCon = *It;
		if (ModCon && ModCon->GetAttachParentActor() == this)
		{
			comps.Add(ModCon);
		}
	}

	return comps;
}


This seems to work, not sure if its the most clean way. Thanks.

As an extension of this question, how do you get the components from a UBlueprint?