Cycle through cameras with UMG button (C++)

I’m trying to cycle through all camera actors(next, previous) with UMG buttons in C++. I’ve a blueprint reference project but have no idea how to implement UMG button clicks with c++ first time. I’d appreciate any help, resources, tutorial or code snippets to get me started. There are two questions.

  1. How to handle button click and in which file and how to get array of all camera actors. I suppose ‘set view target with blend’ will be used to change camera. Its a camera view only project so there is no pawn/character. I have custom player controller and game mode but they are empty. Do I need c++ user widget class too as base for blueprint widget?

  2. How do I access UMG texts/buttons to disable next/previous buttons while camera is moving with blend? And from which class? I would also use it to display actor name in widget on any actor’s mouse over event in c++.

You can do all of this from your custom player controller class.
You need a reference on the widget blueprint created in the editor. From this reference, you will be able to get the UMG widgets contained inside the blueprint and then bind them/disable them.

In your player controller header file you need:

// Your main widget blueprint reference. Set the reference from your player controller blueprint created from the c++ class
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<class UUserWidget>		WidgetBP;

// The widget itself once instantiated
UPROPERTY()
UUserWidget	*MainWidget;

In your player controller cpp file you need: (In BeginPlay)

// Setup input
bShowMouseCursor = true;
UWidgetBlueprintLibrary::SetInputMode_GameAndUI(this);

// Add an instance of your widget blueprint in the world
MainWidget = CreateWidget<UUserWidget>(this, CM_Widget);
if (MainWidget)
	MainWidget->AddToViewport();

Then whenever you want to access a widget, just use MainWidget->GetWidgetFromName(“YourWidgetName”) and cast the resulting UWidget* into a UButton* or any other widget you need to access.

Now to bind your UButton *, you need to create a delegate. Basically, it looks like this:

UWidget *Widget = MainWidget->GetWidgetFromName("YourWidgetName");
if (Widget)
{
UButton *YourButton= static_cast<UButton*>(Widget);
FScriptDelegate	Del;

Del.BindUFunction(this, "YourDelegateFunctionName");
YourButton->OnClicked.Clear();
YourButton->OnClicked.Add(Del);
}

Last thing you need to know is that your delegate function need to be a (public? BlueprintCallable? Not sure) UFUNCTION to be triggered and obviously need to meet the signature for the trigger event to be called (void YourFunction() for a button onclick event)

And finally, to disable your buttons when camera are switching:
First get your cameras using UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACameraActor::StaticClass(), OutputActorsArray); and then set the current one using SetViewTargetWithBlend(YourCamera) in your player controller.
Then in your OnClicked delegate function, set YourButton->SetIsActive(false) then set a timer which will call a function after the blend time has expire to set YourButton->SetIsActive(true)

Thanks for the detailed answer. The way I did it was → created MyUserWidget class → created widget blueprint BPW_Main based on that where I have Next/Previous buttons and Description text which also updates. → In custom MyPlayerController class I have GetText/SetText which I’m binding to description text in the widget and calling ChangeCamera on Next button click.

So I’m doing everything in player controller. Is that the correct way of communication with widgets? Of course I have only fixed camera views in my game and no pawn/character.

There is one problem however. Widget’s Description text is continuously calling GetText so whenever I set some text, it updates in the widget. Is it normal? Or should I use delegates so whenever SetText is called only then ‘once’ text should be updated in the widget?

I add delegates like you mentioned and see how it goes.

Best way of doing it will vary depending what your are attempting to do. Still, the player controller usually is a good solution which enable you having a custom per player specific control but doesn’t offer per pawn control (which you don’t need so that’s fine). As for the text widget, if you don’t need to update it on a per tick basis, I would just use SetText() when I need to to set the text or update it instead of binding the text value or creating a delegate for GetText(). Hope that answers your question.