获取Actor里的某个Component的某个值

刚开始学习C++,想问一下这个功能应该要怎么实现
// 通过Component的类和名字找到Actor里的某个Component的某个参数值

MyBlueprintFunctionLibrary.h

UFUNCTION(BlueprintCallable)
static bool FindComponentValue(AActor* InActor, UClass InComponentClass,FString InComponentStr,FName InPropertyName);
MyBlueprintFunctionLibrary.cpp

bool UMyBlueprintFunctionLibrary::FindComponentValue(AActor* InActor, UClass InComponentClass,FString InComponentStr,FName InPropertyName)
{
    if (InActor == nullptr) return false;

    //获取Actor的类
    UClass* ActorClass = InActor->GetClass();
    if (ActorClass == nullptr) return false;

    //获取Actor的Components

    //for循环Components,找到名称和InComponentStr对应的Component

        //找到属性名称和InPropertyName对应的值并打印
        //如何想要设置这个值,应该如何扩展
        return true;
}
MyBlueprintFunctionLibrary.cpp

bool UMyBlueprintFunctionLibrary::FindComponentValue(AActor* InActor, /*UClass*/TSubclassOf<UActorComponent> InComponentClass,FString InComponentStr,FName InPropertyName)
{
    if (InActor == nullptr) return false;

/*    //获取Actor的类
    UClass* ActorClass = InActor->GetClass();
    if (ActorClass == nullptr) return false;

    //获取Actor的Components

    //for循环Components,找到名称和InComponentStr对应的Component

        //找到属性名称和InPropertyName对应的值并打印
        //如何想要设置这个值,应该如何扩展
        return true;*/

	if (!ComponentClass) return false;
	UActorComponent* FoundComponent = InActor->GetComponentByClass(ComponentClass);
	if (FoundComponent == nullptr) return false;
	FProperty* Property = FoundComponent->GetClass()->FindPropertyByName(InPropertyName);
	if (Property == nullptr) return false;
      //....
}

查了一下文档,GetComponentByClass() 搜索 components 数组并返回指定类的第一个遇到的组件,有相同类的他也只返回第一个,我看他文档的意思是Actor有一个ComponentS数组,所以当时我的想法是看看怎么获得这个数组,然后再循环这个数组,找每一个Component来对比他们的显示名称确定是不是要找的哪个组件,只是找这个文档一直没找到如何获取这个数组

存放Component的地方在…/Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h的4098行

	TSet<TObjectPtr<UActorComponent>> OwnedComponents;

噢是不是就需要自己去修改引擎的源码实现出类似GetComponentByClass()这样的功能,比如GetComponentByDisplayName(),然后编译好再重新来在自己写的这个C++类中调用

UActorComponent* FoundComponent = InActor->GetComponentByDisplayName("XXX");

看来得继续学习怎么编译源码才行了 :rofl:

如果只是为了实现自己“通过一个字符串获取指定组件”这个想法的话可以用

AActor::GetComponentsByTag();

Tag是一个很常用的引擎功能,它不同于class需要先声明再使用,可以随时为Actor打Tag,判断有没有Tag。


图1 在头文件中的声明

图2 在蓝图中使用

图3 在场景大纲中为Actor编辑Tags

而要是为了学习虚幻引擎,编译源码是很好的学习手段。