HUDメッセージの仕掛けで背景表示しVerseでボタン生成してアイテム選択メニューを作成

OneShotBallistic (島コード: 7218-4337-3934)という島で作ったアイテム選択メニューのverseのコードを記載しておきます。

作ってみたものの、この島からこの機能を削除することにしたので、メモ代わりに残しておきます。

目次

アイテム選択メニューのUIの説明

下記画像は「GET」ボタンを押下すると各アイテムを取得することができるアイテム選択メニューの画面キャプチャです。

このメニューは、アイテムの画像などを配置した背景画像用として作ったBlueprintのUIウィジェットをHUDメッセージの仕掛けで表示しており、「GET」や「CLOSE」というボタンだけはVerseによって生成を行っています。

アイテム選択メニューの背景用の Blueprint UI Widget

フォートナイトの本家バリスティックと同じようなアイテムの並びで、画像や文字、背景を作成しておきます。

各アイテムの右下あたりに Verse で「GET」ボタンを表示するつもりなので、右下は空白になるようにしておきました。

アイテム選択メニューのボタンを生成するVerseのコード

アイテム付与の処理なども別のverseファイルとして作成しているのですが、そういう部分は端折って、ここではボタン生成のverseファイルだけを記載します。

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

# NOTE: デバッグ用のログ出力のためのもの
log_weapon_select_menu_device := class(log_channel){}

weapon_select_menu_device := class(creative_device):
    # NOTE: デバッグ用のログ出力のためのもの
    Logger:log = log{Channel:=log_weapon_select_menu_device}
    # UI にテキストとして表示するローカライズ可能なメッセージ
    TextForMyUI<localizes>(InText:string):message = "{InText}"
    # プレイヤーと、そのプレイヤーの UI に追加されている可能性があるウィジェットとの間のマッピング
    var MaybeMyUIPerPlayer:[player]?overlay = map{}

    # インベントリ制御
    # NOTE: 別のverseファイルとして自作したインベントリにアイテム付与する際の処理をまとめたクラス
    @editable
    InventoryCtrl:inventory_control_device = inventory_control_device{}
    # 入力トリガーデバイス
    @editable
    OpenMenuInputTriggerDevice:input_trigger_device = input_trigger_device{}
    # 背景用のHUD
    @editable
    BackgroundHUDMessageDevice:hud_message_device = hud_message_device{}
    # メニューを開くSE
    @editable
    OpenSEAudioPlayerDevice:audio_player_device = audio_player_device{}
    # メニューを閉じるSE
    @editable
    CloseSEAudioPlayerDevice:audio_player_device = audio_player_device{}
    # 武器を選択したSE
    @editable
    SelectSEAudioPlayerDevice:audio_player_device = audio_player_device{}

    # ラウンド開始時
    OnBegin<override>()<suspends>:void=
        # メニューを開く入力トリガーの押下時のイベントリスナー
        OpenMenuInputTriggerDevice.ReleasedEvent.Subscribe(OnOpenWeaponSelectMenuUI)
 
    # ===================================
    # 入力トリガー
    # ===================================
    # 武器選択メニューを開く
    OnOpenWeaponSelectMenuUI(Agent:agent, HoldDuration:float):void=
        OpenWeaponSelectMenuUI(Agent)

    # ===================================
    # 武器選択メニューの処理
    # ===================================
    # 武器選択メニューを開く
    OpenWeaponSelectMenuUI(Agent:agent):void=
        if (InPlayer := player[Agent], PlayerUI := GetPlayerUI[InPlayer]):
            if (MyUI := MaybeMyUIPerPlayer[InPlayer]?):
                # NOTE: デバッグ用ログ出力の条件分岐が残ってるだけ。
                Logger.Print("OpenUI nope")
            else:
                # 武器選択メニューの背景画像を表示
                BackgroundHUDMessageDevice.Show(Agent)
                # 武器選択メニューのUIウィジェットを表示
                NewUI := CreateWeaponSelectMenuUI()
                # NOTE: InputMode := ui_input_mode.All でキャンバス内の要素をインタラクト可能にする
                PlayerUI.AddWidget(NewUI, player_ui_slot{ InputMode := ui_input_mode.All })
                if (set MaybeMyUIPerPlayer[InPlayer] = option{NewUI}) {}
                # SE再生
                OpenSEAudioPlayerDevice.Play(Agent)
    # 武器選択メニューを閉じる
    CloseWeaponSelectMenuUI(Agent:agent):void=
        if (InPlayer := player[Agent], PlayerUI := GetPlayerUI[InPlayer]):
            if (MyUI := MaybeMyUIPerPlayer[InPlayer]?):
                # 武器選択メニューの背景画像を表示
                BackgroundHUDMessageDevice.Hide(Agent)
                # 武器選択メニューのUIウィジェットを非表示にする
                PlayerUI.RemoveWidget(MyUI)
                if (set MaybeMyUIPerPlayer[InPlayer] = false) {}
                 # SE再生
                CloseSEAudioPlayerDevice.Play(Agent)

    # ===================================
    # 武器選択メニューの中で行う処理
    # ===================================
    # 武器を付与する
    # NOTE: InventoryCtrl は別のverseファイルとして自作したインベントリにアイテム付与する際の処理をまとめたクラス
    SelectPistol1(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectPistol1(WidgetMessage.Player) # Hand Cannon
    SelectAssaultRifle1(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectAssaultRifle1(WidgetMessage.Player) # Enforcer Assault Rifle
    SelectAssaultRifle2(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectAssaultRifle2(WidgetMessage.Player) # Striker Assault Rifle
    SelectAssaultRifle3(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectAssaultRifle3(WidgetMessage.Player) # Nemesis Assault Rifle
    SelectSMG1(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectSMG1(WidgetMessage.Player) # Thunder Burst SMG
    SelectSMG2(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectSMG2(WidgetMessage.Player) # Drum Gun
    SelectSMG3(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectSMG3(WidgetMessage.Player) # Hyper SMG
    SelectShotgun1(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectShotgun1(WidgetMessage.Player) # Hammer Pump Shotgun
    SelectShotgun2(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectShotgun2(WidgetMessage.Player) # Frenzy Auto Shotgun
    SelectSniperRifle1(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectSniperRifle1(WidgetMessage.Player) # Reaper Sniper Rifle
    # 消耗品を付与する
    SelectItemBtn1(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectItem1(WidgetMessage.Player) # Impulse Granade
    SelectItemBtn2(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectItem2(WidgetMessage.Player) # Smoke Granade
    SelectItemBtn3(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectItem3(WidgetMessage.Player) # Bubble Shield
    SelectItemBtn4(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectItem4(WidgetMessage.Player) # Frang Granade
    SelectItemBtn5(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectItem5(WidgetMessage.Player) # Flash Bang Granade
    SelectItemBtn6(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectItem6(WidgetMessage.Player) # Recon Granade
    SelectItemBtn7(WidgetMessage:widget_message):void=
        SelectSEAudioPlayerDevice.Play(WidgetMessage.Player) # SE再生
        InventoryCtrl.SelectItem7(WidgetMessage.Player) # Proximity Mine
    # 武器選択メニューを閉じる
    CloseUIinWeaponSelectMenu(WidgetMessage:widget_message):void=
        CloseWeaponSelectMenuUI(WidgetMessage.Player)

    # ===================================
    # UIの生成
    # ===================================
    CreateWeaponSelectMenuUI():overlay =
        # ================= UIウィジェット内に表示するボタン =================
        # 武器ボタン
        UIPistolBtn1:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIAssaultRifleBtn1:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIAssaultRifleBtn2:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIAssaultRifleBtn3:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UISMGBtn1:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UISMGBtn2:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UISMGBtn3:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIShotgunBtn1:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIShotgunBtn2:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UISniperRifleBtn1:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        # ボタン押下時のイベント登録
        UIPistolBtn1.OnClick().Subscribe(SelectPistol1)
        UIAssaultRifleBtn1.OnClick().Subscribe(SelectAssaultRifle1)
        UIAssaultRifleBtn2.OnClick().Subscribe(SelectAssaultRifle2)
        UIAssaultRifleBtn3.OnClick().Subscribe(SelectAssaultRifle3)
        UISMGBtn1.OnClick().Subscribe(SelectSMG1)
        UISMGBtn2.OnClick().Subscribe(SelectSMG2)
        UISMGBtn3.OnClick().Subscribe(SelectSMG3)
        UIShotgunBtn1.OnClick().Subscribe(SelectShotgun1)
        UIShotgunBtn2.OnClick().Subscribe(SelectShotgun2)
        UISniperRifleBtn1.OnClick().Subscribe(SelectSniperRifle1)
        # 消耗品ボタン
        UIItemBtn1:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIItemBtn2:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIItemBtn3:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIItemBtn4:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIItemBtn5:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIItemBtn6:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIItemBtn7:button_quiet = button_quiet{ DefaultText := TextForMyUI("Get") }
        UIItemBtn1.OnClick().Subscribe(SelectItemBtn1)
        UIItemBtn2.OnClick().Subscribe(SelectItemBtn2)
        UIItemBtn3.OnClick().Subscribe(SelectItemBtn3)
        UIItemBtn4.OnClick().Subscribe(SelectItemBtn4)
        UIItemBtn5.OnClick().Subscribe(SelectItemBtn5)
        UIItemBtn6.OnClick().Subscribe(SelectItemBtn6)
        UIItemBtn7.OnClick().Subscribe(SelectItemBtn7)
        # 閉じるボタン
        UIQuietBtn:button_quiet = button_quiet{ DefaultText := TextForMyUI("Close") }
        UIQuietBtn.OnClick().Subscribe(CloseUIinWeaponSelectMenu)
        # ================= UIウィジェットを作成 =================
        WeaponSelectMenuWidget := overlay:
            Slots := array:
                # ================= ボタン1列目 =================
                # フレンジーオートショットガン
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := -560.0, Top := -313.0 }
                    Widget := UIShotgunBtn2
                # ハンマーポンプショットガン
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := -560.0, Top := -133.0 }
                    Widget := UIShotgunBtn1
                # サンダーバーストサブマシンガン
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := -560.0, Top := 47.0 }
                    Widget := UISMGBtn1
                # ハイパーサブマシンガン
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := -560.0, Top := 227.0 }
                    Widget := UISMGBtn3
                # ドラムガン
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := -560.0, Top := 407.0 }
                    Widget := UISMGBtn2
                # ================= ボタン2列目 =================
                # ネメシスアサルトライフル
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := -230.0, Top := -313.0 }
                    Widget := UIAssaultRifleBtn3
                # エンフォーサーアサルトライフル
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := -230.0, Top := -133.0 }
                    Widget := UIAssaultRifleBtn1
                # ストライカーアサルトライフル
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := -230.0, Top := 47.0 }
                    Widget := UIAssaultRifleBtn2
                # ================= ボタン3列目 =================
                # ハンドキャノン
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 100.0, Top := -313.0 }
                    Widget := UIPistolBtn1
                # リーパースナイパーライフル
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 100.0, Top := -133.0 }
                    Widget := UISniperRifleBtn1
                # ================= ボタン4列目 =================
                # インパルスグレネード
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 430.0, Top := -313.0 }
                    Widget := UIItemBtn1
                # バブルシールド
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 430.0, Top := -133.0 }
                    Widget := UIItemBtn3
                # フラググレネード
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 430.0, Top := 47.0 }
                    Widget := UIItemBtn4
                # リーコングレネード
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 430.0, Top := 227.0 }
                    Widget := UIItemBtn6
                # 地雷
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 430.0, Top := 407.0 }
                    Widget := UIItemBtn7
                # ================= ボタン5列目 =================
                # フラッシュバン
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 760.0, Top := -313.0 }
                    Widget := UIItemBtn5
                # スモークグレネード
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Center
                    Padding := margin{ Left := 760.0, Top := -133.0 }
                    Widget := UIItemBtn2
                # ================= 閉じるボタン最下段 =================
                # 閉じるボタン
                overlay_slot:
                    HorizontalAlignment := horizontal_alignment.Center
                    VerticalAlignment := vertical_alignment.Bottom
                    Padding := margin{ Bottom := 50.0 }
                    Widget := UIQuietBtn
        return WeaponSelectMenuWidget
よかったらシェアしてね!
目次