Can i access a templated function from the blueprint system?

Hi all!

I have created a custom UUserWidget class. Here is the code:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Runtime/UMG/Public/UMG.h"
#include "Runtime/UMG/Public/UMGStyle.h"
#include "Runtime/UMG/Public/Slate/SObjectWidget.h"
#include "Runtime/UMG/Public/IUMGModule.h"
#include "Runtime/UMG/Public/Blueprint/UserWidget.h"
#include "BetterPlayerController.h"
#include "BetterUserWidget.generated.h"

class VERTICALSPACESHOOTER_API UBetterUserWidget : public UUserWidget
    // Returns the owning player controller as a BetterPlayerController
    UFUNCTION(BlueprintCallable, Category = "Better UserWidget")
    ABetterPlayerController* GetOwningPlayerController();

    // Gets the widget in the hierarchy root as a custom UserWidget
    template<class T>
    UFUNCTION(BlueprintCallable, Category = "Better UserWidget")    
    T* TGetRootWidget();

// Fill out your copyright notice in the Description page of Project Settings.

#include "VerticalSpaceShooter.h"
#include "BetterUserWidget.h"

ABetterPlayerController* UBetterUserWidget::GetOwningPlayerController()
    if (GetPlayerContext().IsValid())
        return Cast<ABetterPlayerController>(GetPlayerContext().GetPlayerController());

    return nullptr;

template<class T>
T* UBetterUserWidget::TGetRootWidget()
    return Cast<T>(GetRootWidget());

But, when i create a widget that inherits from BetterUserWidget, i can only access to GetOwningPlayerController from the blueprint system.
I’m doing something wrong or is entirely impossible trying to expose templated functions? :frowning:

See ya and thanks in advance!

You can only access UFunctions, templated C++ functions can’t be UFunctions. You need to make a UFunction that takes a TSubClassOf<UWidget> to enable what you’re doing via C++ templates if you want something similar in blueprints.

First, thanks for the quick reply :slight_smile: .

I have a problem, i have changed the function in this way:


// Gets the widget in the hierarchy root as a custom UserWidget    
UFUNCTION(BlueprintCallable, Category = "Better UserWidget")    
TSubclassOf<UBetterUserWidget> GetRootBUWidget();


TSubclassOf<UBetterUserWidget> UBetterUserWidget::GetRootBUWidget()
    TSubclassOf<UBetterUserWidget>* rootWidget = Cast<TSubclassOf<UBetterUserWidget>>(GetRootWidget());
    return *rootWidget;

But i get these errors at compile:
Error 3 error C2039: ‘StaticClass’ : no es un miembro de ‘TSubclassOf<UBetterUserWidget>’
Error 4 error C3861: ‘StaticClass’: no se encontró el identificador

I think this is strange, because UBetterUserWidget is inheriting from UUserWidget, and UUserWidget has the StaticClass() member.

See ya!

TSubclassOf<T> means, a UClass that derives from T, not an instance that derives from T. Sorry, looked closer at how you were using it the first time. If you just want to always cast it to UBetterUserWidget, just always cast it to that and return that.

What are you trying to achieve though? GetRootWidget probably doesn’t do what you want it to do. It returns the first widget in the widget tree of your user widget. Widget trees are isolated for each user widget. So if your UBetterUserWidgets are some how always holding UBetterUserWidgets as their first children then it will work.

I think i have complicated the things too much :S.
Thinking it better, i don’t know what led me to think i needed to use this XD.

What i’m doing is this: I have created a BetterPlayerController C++ class to be able to edit the player action mappings from the blueprint system.
Now, i’m doing the UI to edit the mappings, but, due the fact UUserWidget returns a PlayerController reference, and i wanted a BetterPlayerController one, i decided to make my own UUserWidget and add another method that returns the PlayerController casted to BetterPlayerController.

The GetRootWidget function is mean to return the root widget already casted to my own class (i could have done the casting from the blueprint system, but i think this way is cleaner).

Anyway, thanks for your help, i think i know what was my error, i was approaching the problem from the wrong side :).

See ya!