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 对象。