outside of the Editor GetDisplayName()
should be considered random, even the order in the composition hierarchy “may” not be maintained even between different PIE sessions, and unless you are going to sort it the order from a Get Multiple type action should also be considered random.
the only thing about the name that will be consistent is that it shall include the name of the class, which might not be that helpful.
to solve the given situation directly, this can be done in both Blueprints or C++; if you need to have multiple of these Components then if you give either the Actor, or a component that there shall only be one of the reference to all of these icons, you can then access them directly that way.
- you can put them into a struct, or just given them explicit names.
- you can have specific function for each one, or a singular function that takes like an enumeration or a down and dirty integer
an example of if the Actor has the references exposed in C++ (this is doable in blueprints as well without any C++)
void TargetEntity(const FVector& Start, const FVector& End)
{
FHitResult HitResult;
GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility)
if( HitResult.bBlockingHit)
{
if( AMyActor* OtherActor = Cast<AMyActor>(HitResult.GetActor())
{
if( IsValid(OtherActor))
{
// first bool is the new visibility state, and the second is if it should be propagated to components/children under it
OtherActor->Icon5->SetVisibility(true, true);
}
}
}
}
keep in mind that if something is defined in Blueprints then it should be delt with in Blueprints, if at all possible, because the way the reflection system works Blueprints can “easily” see into C++ but it gets very messy very quickly for C++ to try and see into Blueprints (that is technically the situation where your initial desire to try and string resolve Property names but at the very least you would be doing all the work in the C++ which is “easier” but still a headache that can cause frustrations even among experience programmers)
everything in the function I gave above will also work in Blueprints.
there are still other approaches where you give each of these Icons an integer/enumeration which you assign in the Editor manually (again if you are going to be working with these in C++ then you would want to define the Component in C++ as well)
for the ?function? you provided (I don’t completely understand ?Verse?, so this might not completely map)
// 'by giving the AquireTarget a default value you do not have supply the value if you want the default'
void SetTargetLock ( const FVector& Start, const FVector& End, const FString& IconName, bool AquireTarget = true )
{
FHitResult HitResult;
GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility)
if ( HitResult.bBlockingHit && HitResult.GetActor() != nullptr && IsValid(HitResult.GetActor()) )
{
TArray<UMyWidgetComponent*> ComponentArray;
HitResult.GetActor()->GetComponents<UMyWidgetComponent>(ComponentArray);
for( UMyWidgetComponent* comp : ComponentArray )
{
// this presumes that the name will
if( comp->GetName() == IconName )
{
comp->SetVisibility(AquireTarget, true);
break;
}
}
}
}
in the long run if you have defined your classes and types in Blueprints, I would suggest doing this in Blueprints, unless there is already a large portion of your project in C++, and redefining an Actor, or a ActorComponent in C++ from Blueprints because the CastTo has a few extra processor cycles and can come with loading a type into memory for the lifetime of the blueprint, is like selling your car because the next model year came out.