I am trying to create a reusable health bar for any character in my game. I am using MVVM setup with UMainMVVMViewModelContextResolver for ViewModel Creation.
With all that, I have some issues with ContextResolver as its CreateInstance method provides me with UserWidget, which is fine when I was using it only for the player character. But when I want to use it for NPCs, I need to have an owner character reference to get its ViewModel instance.
As you can see, the Character owns the widget, my MainEnemy class, has a ViewModel instance inside it. So I need to access the Character that owns the widget, to get its view model, and return it from the resolver.
I tried a few things, but there is no method that gets the owner Actor, or Character.
I tried:
ACharacter* OwningCharacter = UserWidget->GetTypedOuter<ACharacter>();
and some other similar variations to get it, but probably itâs not structured as a Parent for it directly.
Here is my current version of the resolver for reference:
UObject* UMainMVVMViewModelContextResolver::CreateInstance(const UClass* ExpectedType, const UUserWidget* UserWidget, const UMVVMView* View) const
{
UE_LOG(LogTemp, Warning, TEXT("UMainMVVMViewModelContextResolver"));
if (!UserWidget)
{
UE_LOG(LogTemp, Warning, TEXT("ContextResolver NO WIDGET"));
return nullptr;
}
// Get the actor that owns this widget (e.g., the enemy character instance).
AActor* OwningActor = UserWidget->GetTypedOuter<AActor>();
if (!OwningActor)
{
UE_LOG(LogTemp, Warning, TEXT("MyViewModelResolver: Widget has no OwningActor."));
return nullptr;
}
// Attempt to cast the owner directly to your ACharacterBase class.
ACharacterBase* CharacterOwner = Cast<ACharacterBase>(OwningActor);
if (CharacterOwner)
{
// If the cast is successful, the owner is the correct type.
// We can now access its ViewModel property and return it.
// NOTE: This assumes your ViewModel property is named 'CharacterViewModel'.
// If you named it something else (e.g., 'ViewModel'), change it here.
UE_LOG(LogTemp, Log, TEXT("MyViewModelResolver: Found owner '%s' of type ACharacterBase. Returning its ViewModel."), *OwningActor->GetName());
return CharacterOwner->VM_Health;
}
else
{
// If the cast fails, the widget's owner is not a child of ACharacterBase.
UE_LOG(LogTemp, Warning, TEXT("MyViewModelResolver: OwningActor '%s' is not of type ACharacterBase."), *OwningActor->GetName());
}
return nullptr;
}
It returns: âMyViewModelResolver: Widget has no OwningActor.â.
I would appreciate it if you could help me figure this out by getting the Character, or maybe there is a better way to have this setup that you may know.