
Announcement
Collapse
No announcement yet.
[TUTORIAL/SNIPPET] Creating a UMG Widget in C++, and delegate example.
Collapse
X
-
Marjane repliedJust in case those who face InventoryUIClass is being NULL like above replies and myself, there is a solution thx to TheJamsh.
Instead of TSubclassOf, use TAssetSubclassOf with LoadSynchronous();
here is new code
Code:UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player, HUD and UI") TAssetSubclassOf<class UInventoryUserWidget> InventoryUIClass; // The instance of the players Inventory UI Widget UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player, HUD and UI") class UInventoryUserWidget* InventoryWidget;
Code:void AMyPlayerController::BeginPlay() { Super::BeginPlay(); // Only create the UI on the local machine (dose not excist on the server.) if (IsLocalPlayerController()) { if (!InventoryWidget) // If the widget is not created and == NULL { InventoryWidget = CreateWidget<UInventoryUserWidget>(this, InventoryUIClass.LoadSynchronous()); // Create Widget if (!InventoryWidget ) return; InventoryWidget->AddToViewport(); // Add it to the viewport so the Construct() method in the UUserWidget:: is run. InventoryWidget->SetVisibility(ESlateVisibility::Hidden); // Set it to hidden so its not open on spawn. } } }
https://forums.unrealengine.com/show...ausing-trouble
this is the thread how I got to know the solution.
Leave a comment:
-
gozu repliedOriginally posted by cridia View PostThis looks like an awesome tutorial! Now, I have a question; would it be possible to have the HUD class be responsible for spawning the widgets? My current implementation causes my game to freeze if I put it into the beginplay function. The reason I want to do this is because for certain functions in my widgets, I want access to canvas functions like project or deproject.
It should work fine from any class (i have done it from gameinstance, playercontroller, and a gamemode for various things)
If it is doing it when it creates it, the best way around this is to create the widget on begin play, and hide it, then unhide it when you wish to show it. this is what im doing from player controller and i do not get a pause.)
My hud is actually a blueprint based off my c++ hud class, that attaches a widget in there.
Something like that might do what you want.
Leave a comment:
-
Kochab repliedCan anyone help me with this? I am getting an error and don't know what it means:
error C2228: left of '.__Internal_RemoveDynamic' must have class/struct/union
error C2228: left of '.__Internal_AddDynamic' must have class/struct/union
Code:if (PC) { // Calls CallPlayerPickupItem() that in turn calls the "BlueprintImplementableEvent" on OnPlayerPickedItem() PC->UI_UpdateScore.RemoveDynamic(this, &USHud::CallUpdateScore); // Remove the delegate before binding it. (Its always safe to unbind a delegate.) PC->UI_UpdateScore.AddDynamic(this, &USHud::CallUpdateScore); // Bind the delegate from the PC that calls the BlueprintImplementableEvent. }
Leave a comment:
-
Kochab repliedOriginally posted by Raikoh View PostHey, if you are having issues with intellisense about not being able to open UserWidget.h you should generate visual studio files to fix it.
Leave a comment:
-
cridia repliedThis looks like an awesome tutorial! Now, I have a question; would it be possible to have the HUD class be responsible for spawning the widgets? My current implementation causes my game to freeze if I put it into the beginplay function. The reason I want to do this is because for certain functions in my widgets, I want access to canvas functions like project or deproject.
Leave a comment:
-
Raikoh repliedHey, if you are having issues with intellisense about not being able to open UserWidget.h you should generate visual studio files to fix it.
Leave a comment:
-
eXi repliedHey there,
this is not my tutorial but the "TSubclassOf<class UUInventoryWidget> InventoryUIClass;" should be set in the Blueprint Default Value
of your PlayerController. Go into your "PlayerController" BP and click on "Class Defaults" at the top. Make sure that you assigned
the correct Class to the "InventoryUIClass" variable here.
Leave a comment:
-
황용수 repliedHi! WCode.
Thanks for yours tutorial.
I did your tutorial, but i can't see widget
because InventoryUIClass is null pointer value.
When does InventoryUIClass set by pointer value?
What's wrong?
I think that widget blueprint not executed.
How can i call widget blueprint?
1. Myproject name is widgettest2.
<widgettest2.h>
Code:#ifndef __WIDGETTEST2_H__ #define __WIDGETTEST2_H__ #include "EngineMinimal.h" //UMG #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" // #endif
Code:// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "Blueprint/UserWidget.h" #include "UInventoryWidget.generated.h" /** * */ UCLASS() class WIDGETTEST2_API UUInventoryWidget : public UUserWidget { GENERATED_BODY() };
<UInventoryWidget.cpp>
Code:// Fill out your copyright notice in the Description page of Project Settings. #include "widgettest2.h" #include "UInventoryWidget.h"
<MyPlayerController.h>
Code:// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "GameFramework/PlayerController.h" #include "MyPlayerController.generated.h" /** * */ UCLASS() class WIDGETTEST2_API AMyPlayerController : public APlayerController { GENERATED_BODY() public: virtual void BeginPlay() override; public: // The class that will be used for the players Inventory UI UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player, HUD and UI") TSubclassOf<class UUInventoryWidget> InventoryUIClass; // The instance of the players Inventory UI Widget UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player, HUD and UI") class UUInventoryWidget* InventoryWidget; };
Code:// Fill out your copyright notice in the Description page of Project Settings. #include "widgettest2.h" #include "MyPlayerController.h" #include "UInventoryWidget.h" void AMyPlayerController::BeginPlay() { Super::BeginPlay(); // Only create the UI on the local machine (dose not excist on the server.) if (IsLocalPlayerController()) { if (InventoryUIClass) // Check the selected UI class is not NULL { if (!InventoryWidget) // If the widget is not created and == NULL { InventoryWidget = CreateWidget<UUInventoryWidget>(this, InventoryUIClass); // Create Widget if (!InventoryWidget) return; InventoryWidget->AddToViewport(); // Add it to the viewport so the Construct() method in the UUserWidget:: is run. InventoryWidget->SetVisibility(ESlateVisibility::Hidden); // Set it to hidden so its not open on spawn. } } } }
<MyWidget - Widget Blueprint>
That's all!!
Help me, please.
Engine Version : 4.7.0
OS : Windows 7
Leave a comment:
-
Elvince repliedThanks for this.
I think for people that are not familiar with Delegate & BlueprintImplementableEvent, you may just update your sample for the delegate part with the .H delegate & BlueprintImplementableEvent declaration so people understand how to setup this.
You can also put the RPC function to demonstrate how you called the delegate.
in all case, it's clearly an useful information.
Leave a comment:
-
[TUTORIAL/SNIPPET] Creating a UMG Widget in C++, and delegate example.
Hey everyone i just wanted to post this quik tutorial about creating widgets in C++.
For a tutorial on How to extend a UUserWidget:: for UMG in C++ see link.
Now doing this is prety straight forward except for when dealing with multiplayer.
And i spent some houers trying diferent solution and this is what i came up with.
1 In your player controller class add two new member variabels like this.
Code:// The class that will be used for the players Inventory UI UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player, HUD and UI") TSubclassOf<class UInventoryUserWidget> InventoryUIClass; // The instance of the players Inventory UI Widget UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Player, HUD and UI") class UInventoryUserWidget* InventoryWidget;
Code:void AMyPlayerController::BeginPlay() { Super::BeginPlay(); // Only create the UI on the local machine (dose not excist on the server.) if (IsLocalPlayerController()) { if (InventoryUIClass) // Check the selected UI class is not NULL { if (!InventoryWidget) // If the widget is not created and == NULL { InventoryWidget = CreateWidget<UInventoryUserWidget>(this, InventoryUIClass); // Create Widget if (!InventoryWidget ) return; InventoryWidget->AddToViewport(); // Add it to the viewport so the Construct() method in the UUserWidget:: is run. InventoryWidget->SetVisibility(ESlateVisibility::Hidden); // Set it to hidden so its not open on spawn. } } } }
Code:void AMyPlayerController::ToggleInventory() { if (bShowingInvetory) bShowingInvetory = false; else bShowingInvetory = true; if (InventoryWidget) { if (bShowingInvetory) { InventoryWidget->SetVisibility(ESlateVisibility::Visible); } else { InventoryWidget->SetVisibility(ESlateVisibility::Hidden); } } }
Now if you are wondering way I don`t create it on the server, how do you have server > client behavior?
I do this by creating delegates on the Player Controller and bind them in the Contruct_Implementation() method, that in turns call a "BlueprintImplementableEvent" to notifie the widget it self so it can behave accordingly.
Note: OnPlayerPickupItem delegate is called from server to client using a Remote Procedure Call (RPC)
Here is a example of this.
Code:void UInventoryUserWidget::Construct_Implementation() { Super::Construct_Implementation(); AMyPlayerController* PC = CAST_TO_MY_PC(GetOwningPlayer()); if (PC) { // Calls CallPlayerPickupItem() that in turn calls the "BlueprintImplementableEvent" on OnPlayerPickedItem() PC->OnPlayerPickupItem.RemoveDynamic(this, &UInventoryUserWidget::CallPlayerPickupItem); // Remove the delegate before binding it. (Its always safe to unbind a delegate.) PC->OnPlayerPickupItem.AddDynamic(this, &UInventoryUserWidget::CallPlayerPickupItem); // Bind the delegate from the PC that calls the BlueprintImplementableEvent. } }
And tought it might be a nice share for anyone else having the issue.
WCodeLast edited by WCode; 11-25-2014, 11:46 AM.
Leave a comment: