如何获取一个Actor的所有属性和公开的变量。

我想创建一个蓝图接口,并在玩家控制器中接入,功能是:发送一个Actor给玩家控制器,让玩家控制器执行在服务器上运行的事件,改变这个Actor的某个属性,所以这个接口有三个参数,要改变的Actor(Actor),要改变的属性(String),要改变的值(Value)。现在遇到的问题是如何在不进行类型转换的情况下通过字符串来获取到这个Actor对应的属性或公开的变量,有没有类似 Find Actor Property / Set Actor Property 这样的节点,或者如何用C++写一个这样的函数暴露出来给蓝图使用

虚幻引擎确实是提供这种功能的,它运用了虚幻引擎的反射,这个反射不是光线传播的那个反射。
https://dev.epicgames.com/documentation/zh-cn/unreal-engine/reflection-system-in-unreal-engine?application_version=5.4

SomeInterface.h

...//some code
virtual SetActorProperty(AActor* InActor, const FString& PropertyName, const FString& Value )
{} = 0;
...//Some other code
SomePlayerController.h

UCLASS()
class SOME_API ASomePlayerController : public APlayerController, SomeInterface
{
...// Some code
    UFUNCTION(BlueprintCallable)
    virtual SetActorProperty(AActor* InActor, const FString& PropertyName, const FString& Value ) override;
...// Some other code
};
SomePlayerController.cpp

bool ASomePlayerController::SetActorProperty(AActor* InActor, FName InPropertyName, const FString& InValue)
{
	if (InActor == nullptr) return false;

	// Get the actor class
	UClass* ActorClass = InActor->GetClass();
	if (ActorClass == nullptr) return false;

	// Get the property
	FProperty* Property = ActorClass->FindPropertyByName(InPropertyName);
	if (Property == nullptr) return false;

	// Set the property value
	Property->ImportText_Direct(*InValue, Property->ContainerPtrToValuePtr<void>(InActor), InActor, PPF_None);

	return true;
}
SomeActor.h

UCLASS()
class ASomeActor : AActor
{
...// Some code
    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    FString testString = "Hello world!";
...// Some other code
};

主楼的需求实现应该就完成了,代码是纯手打的,没有智能提示有些地方可能有错误,交给IDE吧。

1 Like

非常感谢,还想再问一下,如果我不需要设置属性,只是想返回这个属性当前的值应该怎么办呢?

Property->ImportText_Direct(*InValue,Property->ContainerPtrToValuePtr<void>(InActor),InActor,PPF_None);

Property->ExportTextItem_Direct(…)

改成这样之后,他始终只返回字符串,应该要怎么样修改才可以返回PropertyValue对应的类型呢?

FString UMyBlueprintFunctionLibrary::FindActorProperty(AActor* InActor, FName InPropertyName)
{
	//if (InActor == nullptr) return false;

	//Get Actor Class
	UClass* ActorClass = InActor->GetClass();
	//if (ActorClass == nullptr) return false;

	//Get Actor Porperty
	FProperty* Property = ActorClass->FindPropertyByName(InPropertyName);
	//if (Property == nullptr) return false;

	FString PropertyValue;
	Property->ExportTextItem_Direct(PropertyValue, Property->ContainerPtrToValuePtr<void*>(InActor), nullptr, InActor, PPF_None);

	return PropertyValue;
}

模板可以解决这个问题