Removing custom UI after specific event.

Hello !
I’m learning to use custom UI through Verse but after several researches about it, i’m still confused about how to remove a custom UI after my players have been teleported.

Here is my code :

 OnBegin<override>()<suspends> : void =
        # S'abonner à l'événement de téléportation
        TeleportDrop.TeleportedEvent.Subscribe(WrapOnPlayerTeleported)
        EliminationManager1.EliminationEvent.Subscribe(OnPlayerElimination)

        var PlayersUI : []player = Self.GetPlayspace().GetPlayers()
        set AllPlayersCount = GetPlayspace().GetPlayers().Length
        var PlayersTP : string = ToString("{PlayersTeleported}/{AllPlayersCount}")

        if(ValidPlayer := PlayersUI[0]):
            AddUIToPlayer(ValidPlayer)
        
        loop:
            Sleep(0.1)
            if(FirstPlayer : player = PlayersUI[0]):
                if(FortniteCharacter : fort_character = FirstPlayer.GetFortCharacter[]):
                    set PlayersTeleported = PlayersTeleported
                    set PlayersTP = PlayersTP

            UpdateUI()
        
        if(ValidPlayer := PlayersUI[0]):
            AddUIToPlayer(ValidPlayer)
            
        loop:
            Sleep(0.1)
            if(FirstPlayer : player = PlayersUI[0]):
                if(FortniteCharacter : fort_character = FirstPlayer.GetFortCharacter[]):
                    set AllPlayersCountUI = AllPlayersCountUI
            UpdateUI()
    
    CreateUI() : canvas =
        UpdateUI()
        userInterface : canvas = canvas :
            Slots := array:
                canvas_slot:
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y:= 0.5}}
                    Offsets := margin{Top := 300.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
                    Alignment := vector2{X := 0.0, Y := 1.0}
                    SizeToContent := false
                    Widget := TextWidget
        return userInterface 

    UpdateUI() : void =

        Print("Update UI")
        var PlayersTP : string = ToString("{PlayersTeleported}/{AllPlayersCount}")
        TextWidget.SetText(GetPlayerListTP(ToString(PlayersTP)))

    
    GetPlayerListTP<localizes>(PlayersTP2 : string) : message = "TOTAL PLAYERS QUALIFIED FOR THE NEXT ROUND : {PlayersTP2}"


    AddUIToPlayer(Player : agent) : void =
        Print("UI To Player")
        if(PlayerUI := GetPlayerUI[player[Player]]):
            PlayerUI.AddWidget(CreateUI())
    
    RemoveUIToPlayer(Message : widget_message) : void =
        var MaybeMyUIPerPlayer : [player]?canvas = map{}
        if(PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?):
            PlayerUI.RemoveWidget(MyUI)
            if (set MaybeMyUIPerPlayer[Message.Player] = false) {}


EndRound1(TeleportedAgent: agent)<suspends> : void =
            # Calculer le seuil à atteindre
            var ThresholdToReach: float = AllPlayersCount * 2.0
            var PlayersTeleported1:float = PlayersTeleported * 1.0
            var AllPlayers : []agent = GetPlayspace().GetPlayers()
            var NonQualifiedPlayers : []player = array{}
            var PlayersUI : []player = Self.GetPlayspace().GetPlayers()
            var PlayersTP : string = ToString("{PlayersTeleported}/{AllPlayersCount}")

            
            if (PlayersTeleported1 >= ThresholdToReach):  
                
                
                # Afficher le message HUD
                if(ValidPlayer := PlayersUI[0]):
                    Message : widget_message = widget_message{Player := ValidPlayer, Source := TextWidget} # Créez un nouveau widget_message
                    RemoveUIToPlayer(Message)
                    UpdateUI()

I’m sorry if my code is not clear, but my goal is to remove my custom UI when the conditions of EndRound1 function is called. Maybe i have added some superficial information in my code, or something.
I also read that RemoveWidget had some technical issues in some topics…
Hope this is clear


And here is a screen for the second round where my widget is still appearing

If I am understanding your question correctly, you may want to map a canvas to each player…

 var PlayersCustomCanvas: [player]canvas = map{}

…you assign a canvas to each playing using PlayersCustomCanvas and hide/display it using something like…

    # hide/display the Custom UI canvas    
    SetCanvasVisiblity(ThisPlayer: player, bVisible: logic): void =
        if (CustomCanvas := PlayersCustomCanvas[ThisPlayer]):
            if (bVisible?):
                CustomCanvas.SetVisibility(widget_visibility.Visible)
            else:
                CustomCanvas.SetVisibility(widget_visibility.Hidden)
1 Like

Thank you for you help my friend.

but It’s not what i’m looking for. :face_with_diagonal_mouth:

Actually i have settled a qualification system.
The canvas is displayed at the start of the game, and it is updated every 0.1 seconds. When a player qualifies himself, the widget is updating too.
When the limited numbers of players teleported is reached (ThresoldToReach) i want to remove or hide the text “Total players qualified for the next round:”

Actually i don’t even know the difference between canvas and widget… I just want to use a text that can be updated in real time to give information about how many players have been qualified in real time…

I hope it is more clear at this point lmao :sweat_smile:

EDIT : i’ve tried to add the function as you suggested but nothing happened.

Well don’t give up. The code I gave you was pulled directly from a published island of mine that has no HUD issues.

You might want to think of a canvas as a drawing board for placing widgets.

Also, unlike Apple’s iOS widget system where it was a huge pain to force individual elements to update, I have found zero issues with the UEFN widget system. But then I am mostly just placing text and boxes on the screen with values that update every second or so.

(Also, have you just tried updating the text to “” at that point?)

1 Like

i’ve succesfully hidden the current widget but I want to add this widget to all players and not only one.
When i start my game, only one player can see this widget. So i’m trying to fix that but i have an error when i call AddUiToPlayer… Sorry for this nooby question :sweat_smile:
Maybe i have to change something in the function ?

        var PlayersUI : []player = GetPlayspace().GetPlayers()
        set AllPlayersCount = GetPlayspace().GetPlayers().Length
        var PlayersTP : string = ToString("{PlayersTeleported}/{AllPlayersCount}")


        
        AddUIToPlayer(PlayersUI) # This function parameter expects a value of type agent, but this argument is an incompatible value of type []player.
        
        loop:
            Sleep(0.1)
            if(FirstPlayer : player = PlayersUI[0]):
                if(FortniteCharacter : fort_character = FirstPlayer.GetFortCharacter[]):

                    UpdateUI()

    AddUIToPlayer(Player : agent) : void =
            Print("UI To Player")
            if(PlayerUI := GetPlayerUI[player[Player]]):
                    PlayerUI.AddWidget(CreateUI())

I did it like the example below, but if you want to allow players to join mid-game, you could do it an actor at a time during each players’ first spawn by having an array of player_spawner_device’s and listening to their SpawnedEvents.

var PlayersCustomCanvas: [player]canvas = map{}

 # set UI on all players around at the start of the match
 for (thisPlayer: Self.GetPlayspace().GetPlayers()):
       if (PlayerUI := GetPlayerUI[thisPlayer]): 
           var NewCanvas: canvas = CreateCanvas()               
           PlayerUI.AddWidget(NewCanvas)
           if:
               set PlayersCustomCanvas[thisPlayer] = NewCanvas
          then:
               SetCanvasVisiblity(thisPlayer, true) 

Just looking at what you did, I see a Sleep(0.1) that I have no idea why it’s there and looking at “PlayersUI[0]” I fear that you may be using just the first item of an array which I guess is possible, but is generally not what I’d expect. There are many ways of doing things, so I don’t want to assume my way is the best.

1 Like

You resolved my problem about how to hide UI, thank you very much but i’m facing another problem :
this UI is only displayed to only one player and what you suggested doesn’t work in my case…

I just need to display the same UI on all players that enter in the island, i’m not looking for other things and it seems to be very difficult to settle imo…

I tried this way from this topic : How do I Show a UI Widget and Update it to Every Player in game - #3 by YouTube_Giova

But still not effective…
I’m sorry but i’m learning Verse since 2 months and i have low experience in programming.

So i modified some parts of my code :

    var TextWidget : text_block = text_block{DefaultTextColor := color{R:=1.0, G := 1.0, B:= 1.0}}
    
  

    OnBegin<override>()<suspends> : void =
        TeleportDrop.TeleportedEvent.Subscribe(WrapOnPlayerTeleported)
        EliminationManager1.EliminationEvent.Subscribe(OnPlayerElimination)

        var PlayersUI : []player = GetPlayspace().GetPlayers() #Get All Players
        set AllPlayersCount = GetPlayspace().GetPlayers().Length #Get sum of all players
        var PlayersTP : string = ToString("{PlayersTeleported}/{AllPlayersCount}") 


        for(Player : PlayersUI):
            AddUIToPlayer(Player)
        
        
        loop:
            for(Player : PlayersUI):
                if(FortniteCharacter : fort_character = Player.GetFortCharacter[]):
                     UpdateUI()

    AddUIToPlayer(Player : agent) : void =

            if(PlayerUI := GetPlayerUI[player[Player]]):
                Print("UI To Player")
                PlayerUI.AddWidget(CreateUI(Player))
    
    CreateUI(Player : agent) : canvas =
        UpdateUI()
        userInterface : canvas = canvas :
            Slots := array:
                canvas_slot:
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y:= 0.5}}
                    Offsets := margin{Top := 300.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
                    Alignment := vector2{X := 0.0, Y := 1.0}
                    SizeToContent := false
                    Widget := TextWidget
        return userInterface 

    UpdateUI() : void =

        Print("Update UI")
        var PlayersTP : string = ToString("{PlayersTeleported}/{AllPlayersCount}")
        TextWidget.SetText(GetPlayerListTP(ToString(PlayersTP)))

        
    GetPlayerListTP<localizes>(PlayersTP2 : string) : message = "TOTAL PLAYERS QUALIFIED FOR THE NEXT ROUND : {PlayersTP2}"

What’s wrong with this code :sob: :sob:

I’m not an expert, but I believe…

var PlayersCustomCanvas: [player]canvas = map{}

…is the concept to try to grasp. Most people (I don’t know if it’s the only way) make an array of canvasses and give each player one.

Suppose you sent a message to an iPad and handed the iPad to player 1, then took it away and handed it to player 2, then took it away and handed it to player 3, etc. Only one player would have the message. If you gave EVERY player an iPad, then you could send a message to anyone and everyone.

If there is an Epic staff person around they can correct me if the concept is wrong.

This is my code now.
Doesn’t work anymore…
I don’t know if i’m doing this right, i think i don’t understand where you expect me to place these lines of code :sweat_smile:

var TextWidget : text_block = text_block{DefaultTextColor := color{R:=1.0, G := 1.0, B:= 1.0}}

    OnBegin<override>()<suspends> : void =
        # S'abonner à l'événement de téléportation
        TeleportDrop.TeleportedEvent.Subscribe(WrapOnPlayerTeleported)
        EliminationManager1.EliminationEvent.Subscribe(OnPlayerElimination)

        var PlayersUI : []player = GetPlayspace().GetPlayers()
        set AllPlayersCount = GetPlayspace().GetPlayers().Length
        var PlayersTP : string = ToString("{PlayersTeleported}/{AllPlayersCount}")
        


        for(Player : PlayersUI):
            AddUIToPlayer(Player)
        
        
        loop:
            Sleep(0.1)
            for(Player : PlayersUI):
                if(FortniteCharacter : fort_character = Player.GetFortCharacter[]):

                    UpdateUI()

    SetCanvasVisiblity(ThisPlayer: player, bVisible: logic): void =
        var PlayersCustomCanvas: [player]canvas = map{}
        if (CustomCanvas := PlayersCustomCanvas[ThisPlayer]):
            if (bVisible?):
                CustomCanvas.SetVisibility(widget_visibility.Visible)
            else:
                CustomCanvas.SetVisibility(widget_visibility.Hidden)

    AddUIToPlayer(Player : agent) : void =
        var PlayersCustomCanvas: [player]canvas = map{}

        for (thisPlayer: Self.GetPlayspace().GetPlayers()):
            if (PlayerUI := GetPlayerUI[thisPlayer]): 
                var NewCanvas: canvas = CreateUI()               
                PlayerUI.AddWidget(NewCanvas)
                if:
                    set PlayersCustomCanvas[thisPlayer] = NewCanvas
               then:
                    SetCanvasVisiblity(thisPlayer, true) 
    
    CreateUI() : canvas =
        var PlayersCustomCanvas: [player]canvas = map{}
        UpdateUI()
    
        
        userInterface : canvas = canvas :
            Slots := array:
                canvas_slot:
                    Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.5}, Maximum := vector2{X := 0.0, Y:= 0.5}}
                    Offsets := margin{Top := 300.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
                    Alignment := vector2{X := 0.0, Y := 1.0}
                    SizeToContent := false
                    Widget := TextWidget
        return userInterface 

    UpdateUI() : void =

        Print("Update UI")
        var PlayersTP : string = ToString("{PlayersTeleported}/{AllPlayersCount}")
        TextWidget.SetText(GetPlayerListTP(ToString(PlayersTP)))

        
    GetPlayerListTP<localizes>(PlayersTP2 : string) : message = "TOTAL PLAYERS QUALIFIED FOR THE NEXT ROUND : {PlayersTP2}"