Search code examples
c++castingunreal-engine4

UE4 cast to specific class from UUserWidget C++


Let's assume i have 3 cpp class.

1- Afirst_class : public AActor

2- Asecond_class : public AActor

3- Uwidget_class : public UUserWidget

I'm trying to cast from Uwidget_class to Asecond_class. After that from Asecond_class to Afirst_class.

When i click the UButton(defined in Uwidget_class), OnClicked dynamic executing the related function. In this function i want to cast Asecond_class. Let me visualize that:

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"));
    }
}

Always test_actor will be nullptr. When i use the same casting from Asecond_class to Afirst_class it works. Should i casting differently when i am using UUserWidget ?

How can i get this Asecond_class in UUserWidget? Thanks in advance.


Solution

  • Like George said in his comment, that cannot work. Cast is for moving around an inheritance tree, but only along the parts of that tree that are directly related to the actual class of the object being referenced.

    So you could cast both your widget and actors to UObjects, but I suspect that's about as common as they'll get.

    It sounds like you need to grab the actor you want at an earlier stage, and save it in a variable (right click, "promote to variable" in blueprint, but you're in c++ so just declare a member variable and use it... is this what test_actor is for?). And later, rather than the casting something unrelated to the end product you want, just use the member variable.


    It seems like you're missing a fundamental understanding of what "casting" is.

    There are two kinds of casting. Up and down.

    "Up casting" (and I'm sure there are other terms too) is taking your Asecond_class, and cast it back into an AActor, or anything else higher up the inheritance tree.

    "Down casting" (other terms yada yada), is taking a pointer or reference of an AActor and trying to cast it to an Asecond_class. If the AActor in question was created as an instance of one of the 141 other things that inherit from AActor, then trying to cast it to Asecond_actor will fail, and rightly so. Treating the memory set aside for an AGameplayAbilityTargetActor like it was an Asecond_actor would be Bad... like "crossing the streams" Bad (that's a Ghostbusters reference for those of you not up on your US popular culture).

    There's actually considerably more than 141. I searched the UE4_26 codebase for ": public AActor", and it returned 141 hits. That doesn't include things that inherit from more than one base class (not for the faint of heart), or things that inherit from any of the aforemented 141 instances of things that inherit from AActor first.

    There are other complexities to casting, but I suggest you wrap your head around this properly before you try to understand what a "virtual base class" is, and why C++ needs such a thing in the first place.