UE4 从 UUserWidget C++ 转换为特定 class
UE4 cast to specific class from UUserWidget C++
假设我有 3 cpp class。
1- Afirst_class : public AActor
2- Asecond_class : public AActor
3- Uwidget_class : public UUserWidget
我正在尝试从 Uwidget_class 转换为 Asecond_class。之后从 Asecond_class 到 Afirst_class.
当我点击UButton(在Uwidget_class中定义)时,OnClicked动态执行相关功能。在这个函数中,我想转换 Asecond_class。让我想象一下:
Uwidget_class.h :
UPROPERTY(meta = (BindWidget))
class UTextBlock* button_text;
UPROPERTY(meta = (BindWidget))
class UButton* button_to_press;
public:
UPROPERTY()
Asecond_class * test_actor;
Uwidget_class.cpp :
void Uwidget_class::NativeConstruct(){
Super::NativeConstruct();
button_to_press-> OnClicked.AddUniqueDynamic(this,&Uwidget_class::on_click_cast_func);
}
void Uwidget_class::on_click_cast_func(){
test_actor = Cast<Asecond_class >(this); //problem might be "this" parameter?
if (test_actor ==nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("DIDN'T CAST SUCCESSFULLY"));
}
else {
UE_LOG(LogTemp, Warning, TEXT("CASTED SUCCESSFULLY"));
}
}
总是 test_actor 将是 nullptr。当我使用从 Asecond_class 到 Afirst_class 的相同转换时,它起作用了。我在使用 UUserWidget 时是否应该进行不同的转换?
如何在 UUserWidget 中获取此 Asecond_class?提前致谢。
正如乔治在他的评论中所说,那是行不通的。 Cast 用于围绕继承树移动,但仅沿着该树中与被引用对象的实际 class 直接相关的部分移动。
因此,您可以将小部件和演员都投射到 UObjects
,但我怀疑这与他们将获得的一样普遍。
听起来你需要在早期阶段抓取你想要的演员,并将其保存在一个变量中(右键单击,蓝图中的“提升为变量”,但你在 c++ 中,所以只需声明一个成员变量并使用它...这是 test_actor
的用途吗?)。之后,不要强制转换与您想要的最终产品无关的内容,只需使用成员变量即可。
您似乎对什么是“转换”没有基本的了解。
铸造有两种。上下。
“Up casting”(我敢肯定还有其他术语)正在将您的 Asecond_class
转换回 AActor
或继承树上层的任何其他内容.
“向下转换”(其他术语 yada yada)正在获取 AActor
的指针或引用,并且 尝试 将其转换为 Asecond_class
.如果所讨论的 AActor
是作为从 AActor
继承的 141 个其他事物之一的实例创建的,那么尝试将其转换为 Asecond_actor
将失败,这是正确的。像对待 Asecond_actor 一样对待为 AGameplayAbilityTargetActor
预留的内存会很糟糕......就像“穿越溪流”一样糟糕(对于那些不了解美国流行文化的人来说,这是捉鬼敢死队的参考).
实际上远远超过 141 个。我在 UE4_26 代码库中搜索“: public AActor”,它返回了 141 个匹配项。这不包括继承自多个基础的事物 class(不适合胆小的人),也不包括继承自 AActor 首先继承的上述 141 个实例中的任何一个的事物。
转换还有其他复杂性,但我建议您在尝试理解“虚拟基础 class”是什么以及为什么 C++ 首先需要这样的东西之前先好好思考一下这个问题地点。
正如其他人所说,您正试图将 UUserWidget 对象 this
转换为 AActor,这将不起作用,因为小部件本身不是从 AActor 派生的。
解决方案:如果你真的想从你的小部件访问“Asecond_class”(AActor),你需要保存一个指向该对象的指针AActor*
(例如,当小部件被初始化时)并使用你演员的那个指针。但是,如果该对象始终是“Asecond_class”,您可以简单地存储一个 Asecond_class*
并完全避免强制转换。
使用存储在小部件中的通用 AActor 指针成员:
AActor* savedActorPtr;
// pass in as argument when the widget is initialized and set the saved pointer
那么,如果你真的要投:
Asecond_class* secActorPtr = Cast<Asecond_class>(savedActorPtr);
if (secActorPtr)
{
// cast successful, you can now use secActorPtr to access the actor
secActorPtr->yourClickFunction();
}
或者,避免不必要的转换:
Asecond_class* savedSecPtr;
// same as savedActorPtr before, but always using target type, so no need to cast
if (savedSecPtr)
{
savedSecPtr->yourClickFunction();
}
else
{
// error: pointer was never set or actor was deleted
}
假设您真正想要的是从不相关的 UUserWidget 访问 actor 对象。
假设我有 3 cpp class。
1- Afirst_class : public AActor
2- Asecond_class : public AActor
3- Uwidget_class : public UUserWidget
我正在尝试从 Uwidget_class 转换为 Asecond_class。之后从 Asecond_class 到 Afirst_class.
当我点击UButton(在Uwidget_class中定义)时,OnClicked动态执行相关功能。在这个函数中,我想转换 Asecond_class。让我想象一下:
Uwidget_class.h :
UPROPERTY(meta = (BindWidget))
class UTextBlock* button_text;
UPROPERTY(meta = (BindWidget))
class UButton* button_to_press;
public:
UPROPERTY()
Asecond_class * test_actor;
Uwidget_class.cpp :
void Uwidget_class::NativeConstruct(){
Super::NativeConstruct();
button_to_press-> OnClicked.AddUniqueDynamic(this,&Uwidget_class::on_click_cast_func);
}
void Uwidget_class::on_click_cast_func(){
test_actor = Cast<Asecond_class >(this); //problem might be "this" parameter?
if (test_actor ==nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("DIDN'T CAST SUCCESSFULLY"));
}
else {
UE_LOG(LogTemp, Warning, TEXT("CASTED SUCCESSFULLY"));
}
}
总是 test_actor 将是 nullptr。当我使用从 Asecond_class 到 Afirst_class 的相同转换时,它起作用了。我在使用 UUserWidget 时是否应该进行不同的转换?
如何在 UUserWidget 中获取此 Asecond_class?提前致谢。
正如乔治在他的评论中所说,那是行不通的。 Cast 用于围绕继承树移动,但仅沿着该树中与被引用对象的实际 class 直接相关的部分移动。
因此,您可以将小部件和演员都投射到 UObjects
,但我怀疑这与他们将获得的一样普遍。
听起来你需要在早期阶段抓取你想要的演员,并将其保存在一个变量中(右键单击,蓝图中的“提升为变量”,但你在 c++ 中,所以只需声明一个成员变量并使用它...这是 test_actor
的用途吗?)。之后,不要强制转换与您想要的最终产品无关的内容,只需使用成员变量即可。
您似乎对什么是“转换”没有基本的了解。
铸造有两种。上下。
“Up casting”(我敢肯定还有其他术语)正在将您的 Asecond_class
转换回 AActor
或继承树上层的任何其他内容.
“向下转换”(其他术语 yada yada)正在获取 AActor
的指针或引用,并且 尝试 将其转换为 Asecond_class
.如果所讨论的 AActor
是作为从 AActor
继承的 141 个其他事物之一的实例创建的,那么尝试将其转换为 Asecond_actor
将失败,这是正确的。像对待 Asecond_actor 一样对待为 AGameplayAbilityTargetActor
预留的内存会很糟糕......就像“穿越溪流”一样糟糕(对于那些不了解美国流行文化的人来说,这是捉鬼敢死队的参考).
实际上远远超过 141 个。我在 UE4_26 代码库中搜索“: public AActor”,它返回了 141 个匹配项。这不包括继承自多个基础的事物 class(不适合胆小的人),也不包括继承自 AActor 首先继承的上述 141 个实例中的任何一个的事物。
转换还有其他复杂性,但我建议您在尝试理解“虚拟基础 class”是什么以及为什么 C++ 首先需要这样的东西之前先好好思考一下这个问题地点。
正如其他人所说,您正试图将 UUserWidget 对象 this
转换为 AActor,这将不起作用,因为小部件本身不是从 AActor 派生的。
解决方案:如果你真的想从你的小部件访问“Asecond_class”(AActor),你需要保存一个指向该对象的指针AActor*
(例如,当小部件被初始化时)并使用你演员的那个指针。但是,如果该对象始终是“Asecond_class”,您可以简单地存储一个 Asecond_class*
并完全避免强制转换。
使用存储在小部件中的通用 AActor 指针成员:
AActor* savedActorPtr;
// pass in as argument when the widget is initialized and set the saved pointer
那么,如果你真的要投:
Asecond_class* secActorPtr = Cast<Asecond_class>(savedActorPtr);
if (secActorPtr)
{
// cast successful, you can now use secActorPtr to access the actor
secActorPtr->yourClickFunction();
}
或者,避免不必要的转换:
Asecond_class* savedSecPtr;
// same as savedActorPtr before, but always using target type, so no need to cast
if (savedSecPtr)
{
savedSecPtr->yourClickFunction();
}
else
{
// error: pointer was never set or actor was deleted
}
假设您真正想要的是从不相关的 UUserWidget 访问 actor 对象。