Verse UI - How to keep widgets on first players screen without second player removing them?

Hey Twin! I tried to integrate your OnlyUp script into my dialog script and I got partially somewhere but it’s still pretty wacky. :laughing: My goal is a little different from yours because I have a UI button click. I made the class concrete so that I could use editable variables for it, hope that’s ok.

This is what I have so far. What happens in testing is that the canvas appears the first time on Button Device press, which is good. But then the button click gets weird because the sequence goes “Row 1 Part 1” then “Row 1 Part 3” then Part 1 again, then Part 3 again, then deletes the canvas. Instead of going Part 1, Part 2, Part 3, remove canvas. And after the canvas is gone the first time I can’t get it to come back again on button device press :frowning_with_open_mouth:

What do you think is going on here?

using { /Fortnite.com/Devices }                 
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Simulation }

ui_dialog_simple1 := class(creative_device):

    @editable 
    ButtonUIAdd : button_device = button_device {} 

    @editable 
    Title : string = "Title"

    @editable
    TextRow1: []string = array:
        "Row 1 Part 1"
        "Row 1 Part 2"
        "Row 1 Part 3"
    
    var DisplayMap: [player]?dialog_widget = map{}

    OnBegin<override>()<suspends>:void=
        Print("UI Popup NextExit Device Began")
        ButtonUIAdd.InteractedWithEvent.Subscribe(HandleButtonUIAddInteraction)

    HandleButtonUIAddInteraction(Agent:agent):void=
        Print("Button Device Interacted With")
        AllPlayers := GetPlayspace().GetPlayers()
        for (Player : AllPlayers):
            DialogWidgetInstance := dialog_widget:
                VerseDevice := Self
                InstancePlayer := option{Player} 
                DialogTitle := Title 
                DialogRow1 := TextRow1 
            if (not DisplayMap[Player], set DisplayMap[Player] = option{DialogWidgetInstance}):
                DialogWidgetInstance.CreateMyUI()
                #if (Agent := agent[Player]):
                var currentTextPart : int = 0 
                DialogWidgetInstance.AddCanvas(Agent)
                DialogWidgetInstance.UpdateText(currentTextPart)

    #===== Dialog Widget Class ==========================================================

dialog_widget := class<concrete>():

    StringToMessage<localizes>(value:string) : message = "{value}"

    var VerseDevice : ui_dialog_simple1 = ui_dialog_simple1{}
    InstancePlayer: ?player = false ###

    WidgetRow1:text_block = text_block {}
    WidgetUIButton:button_regular = button_regular {} 

    var MaybeMyUIPerPlayer : [player]?canvas = map{}
    var currentTextPart : int = 0 

    DialogTitle : string = ""
    DialogRow1: []string = array{}

    HandleUIButtonClick(Message: widget_message):void= 
        Print("UI Button Clicked")
        if (currentTextPart = DialogRow1.Length):
            RemoveCanvas(Message)
            set currentTextPart = 0
  
        else:  
            if (currentTextPart <= DialogRow1.Length - 1):
                if (currentTextPart = DialogRow1.Length - 1):
                    UpdateText(currentTextPart)
                else:
                    UpdateText(currentTextPart)   
                    
    UpdateText(Index:int):void= 
        Print("Update Text")
        if(currentStr := DialogRow1[Index]):
            WidgetRow1.SetText(StringToMessage(currentStr))
        set currentTextPart += 1 

    AddCanvas(Agent:agent):void=
        Print("Add Canvas")
        if (InPlayer := player[Agent], PlayerUI := GetPlayerUI[InPlayer]):
            if (MyUI := MaybeMyUIPerPlayer[InPlayer]?):
                PlayerUI.RemoveWidget(MyUI)
                if (set MaybeMyUIPerPlayer[InPlayer] = false) {}
            else:
                NewUI := CreateMyUI()
                PlayerUI.AddWidget(NewUI, player_ui_slot{InputMode := ui_input_mode.All})
                if (set MaybeMyUIPerPlayer[InPlayer] = option{NewUI}) {}

    CreateMyUI():canvas=
        Print("Create UI")
        WidgetUIButton.OnClick().Subscribe(HandleUIButtonClick)
        WidgetTitle:text_block = text_block: 
            DefaultText := {StringToMessage(DialogTitle)}

        NewCanvas := canvas:
            Slots := array:
                canvas_slot:
                    Anchors := anchors:
                        Minimum := vector2{X := 0.5, Y := 0.25}
                        Maximum := vector2{X := 0.5, Y := 0.25}
                    Alignment := vector2{X := 0.5, Y := 0.5}
                    SizeToContent := true
                    Widget := stack_box:
                        Orientation := orientation.Vertical
                        Slots := array:
                            stack_box_slot:
                                Widget := WidgetTitle
                            stack_box_slot: 
                                Widget := WidgetRow1 
                            stack_box_slot:
                                Widget := WidgetUIButton

        return NewCanvas
        
    RemoveCanvas(Message: widget_message):void=
        if (PlayerUI := GetPlayerUI[Message.Player], MyUI := MaybeMyUIPerPlayer[Message.Player]?, SelectedButton := text_button_base[Message.Source]):
            Print("Remove Canvas")
            PlayerUI.RemoveWidget(MyUI)
            if (set MaybeMyUIPerPlayer[Message.Player] = false) {}