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.
2 Override the BeginPlay() method in your Player Controller class.
3 Open and close inventory UI example.
Thats it! 
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.
Hope this was helpful i spent some time on the crash i got when not checking for IsLocalPlayerController().
And tought it might be a nice share for anyone else having the issue.
WCode
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.
WCode
Comment