【问题标题】:UE4 cast to specific class from UUserWidget C++UE4 从 UUserWidget C++ 转换为特定类
【发布时间】:2021-06-17 09:09:39
【问题描述】:

假设我有 3 个 cpp 类。

1- Afirst_class : 公共 AActor

2- Asecond_class : 公共 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?提前致谢。

【问题讨论】:

  • 从小部件投射到演员没有任何意义。为了使铸造起作用,所涉及的两个对象必须相同。例如,从演员到角色的演员只有在演员实际上是一个角色时才有效。唯一能让你知道的是关于你已经拥有的物体的更多信息。

标签: c++ casting unreal-engine4


【解决方案1】:

就像乔治在他的评论中所说的那样,那是行不通的。 Cast 用于在继承树中移动,但只能沿着该树中与被引用对象的实际类直接相关的部分移动。

所以你可以将你的小部件和演员都投射到UObjects,但我怀疑这和他们一样普遍。

听起来你需要在更早的阶段抓住你想要的演员,并将其保存在一个变量中(右键单击,蓝图中的“提升为变量”,但你在 c++ 中,所以只需声明一个成员变量和使用它...这是test_actor 的用途吗?)。之后,不要强制转换与您想要的最终产品无关的东西,只需使用成员变量即可。


您似乎对什么是“铸造”缺乏基本的了解。

有两种类型的铸造。上下。

“向上转换”(我相信还有其他术语)将您的Asecond_class 转换回AActor,或者继承树上更高的任何其他内容。

“向下转换”(其他术语 yada yada),正在获取 AActor 的指针或引用,并尝试将其转换为 Asecond_class。如果有问题的AActor 是作为继承自AActor 的其他141 个事物之一的实例创建的,那么尝试将其强制转换为Asecond_actor 将失败,这是正确的。将留给 AGameplayAbilityTargetActor 的内存当作 Asecond_actor 处理会很糟糕……就像“穿越溪流”一样糟糕(对于那些不了解美国流行文化的人来说,这是《捉鬼敢死队》的参考)。

实际上比 141 多得多。我在 UE4_26 代码库中搜索“:public AActor”,它返回了 141 个命中。这不包括从多个基类继承的东西(不适合胆小的人),或从上述 141 个先从 AActor 继承的东西实例中的任何一个继承的东西。

强制转换还有其他复杂性,但我建议您在尝试理解什么是“虚拟基类”以及为什么 C++ 首先需要这样的东西之前正确地解决这个问题。

【讨论】:

    【解决方案2】:

    正如其他人所说,您正在尝试将 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 访问一个演员对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-18
      • 2019-04-10
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2018-03-27
      • 2019-02-23
      • 2020-08-26
      相关资源
      最近更新 更多