How to Create a Lobby Menu
This guide shows you how to create a Lobby Menu (corona mode) using ScaleformUI. You will learn how to set up the three-column layout, add settings, players, and mission details, and handle user interactions.
Step 1: Initialize the MainView Container
The MainView is the entry point for the Lobby Menu. It automatically configures the layout for corona mode.
C#
using ScaleformUI;
using ScaleformUI.LobbyMenu;
using ScaleformUI.PauseMenus.Elements.Columns;
using ScaleformUI.PauseMenus.Elements.Panels;
using CitizenFX.Core;
using System;
public async void CreateLobbyMenu()
{
// Create the main container
MainView lobbyMenu = new MainView("Lobby Menu", "Lobby Subtitle", "Detail 1", "Detail 2", "Detail 3");
lobbyMenu.CanPlayerCloseMenu = true;
lobbyMenu.TabsColor = HudColor.HUD_COLOUR_PINK;
// Set up a ped headshot for the header picture
int mugshot = API.RegisterPedheadshot(Game.PlayerPed.Handle);
while (!API.IsPedheadshotReady(mugshot)) await BaseScript.Delay(1);
string ped_txd = API.GetPedheadshotTxdString(mugshot);
lobbyMenu.HeaderPicture = new Tuple<string, string>(ped_txd, ped_txd);
API.UnregisterPedheadshot(mugshot);
}
Lua
function CreateLobbyMenu()
-- Create the main container
local lobbyMenu = MainView.New("Lobby Menu", "Lobby Subtitle", "Detail 1", "Detail 2", "Detail 3")
lobbyMenu:CanPlayerCloseMenu(true)
lobbyMenu:TabsColor(Colours.HUD_COLOUR_PINK)
-- Set up a ped headshot for the header picture
local handle = RegisterPedheadshot(PlayerPedId())
while not IsPedheadshotReady(handle) or not IsPedheadshotValid(handle) do Citizen.Wait(0) end
local txd = GetPedheadshotTxdString(handle)
lobbyMenu:HeaderPicture(txd, txd)
UnregisterPedheadshot(handle)
end
Step 2: Set Up the Columns
A Lobby Menu consists of three columns: a left column (usually settings), a center column (usually players), and a right column (usually mission details or player stats).
C#
// Create the columns
SettingsListColumn settingsCol = new SettingsListColumn("SETTINGS", 16);
PlayerListColumn playersCol = new PlayerListColumn("PLAYERS", 16);
MissionDetailsPanel detailsCol = new MissionDetailsPanel("DETAILS");
// Assign the columns to the lobby menu
lobbyMenu.SetupLeftColumn(settingsCol);
lobbyMenu.SetupCenterColumn(playersCol);
lobbyMenu.SetupRightColumn(detailsCol);
Lua
-- Create the columns
local settingsCol = SettingsListColumn.New("SETTINGS", 16)
local playersCol = PlayerListColumn.New("PLAYERS", 16)
local detailsCol = MissionDetailsPanel.New("DETAILS")
-- Assign the columns to the lobby menu
lobbyMenu:SetupLeftColumn(settingsCol)
lobbyMenu:SetupCenterColumn(playersCol)
lobbyMenu:SetupRightColumn(detailsCol)
Step 3: Populate the Columns
Add settings items, players, and details to the columns.
C#
// 1. Populate Settings Column
UIMenuItem startItem = new UIMenuItem("Start Match", "Start the match immediately.");
UIMenuCheckboxItem friendlyFire = new UIMenuCheckboxItem("Friendly Fire", true, "Toggle friendly fire.");
settingsCol.AddSettings(startItem);
settingsCol.AddSettings(friendlyFire);
// 2. Populate Players Column
CrewTag crew = new CrewTag("DEV", false, false, CrewHierarchy.Leader, SColor.HUD_Green);
FriendItem playerItem = new FriendItem(Game.Player.Name, SColor.HUD_Green, true, 100, "Ready", crew);
playerItem.SetLeftIcon(LobbyBadgeIcon.IS_PC_PLAYER);
playerItem.ClonePed = Game.PlayerPed;
// Create a stats panel for the player
PlayerStatsPanel statsPanel = new PlayerStatsPanel("Player Stats", SColor.HUD_Green);
statsPanel.RankInfo.RankLevel = 50;
statsPanel.RankInfo.LowLabel = "Rank 50";
statsPanel.AddStat(new PlayerStatsPanelStatItem("Kills", "Total kills", 75));
statsPanel.AddStat(new PlayerStatsPanelStatItem("Deaths", "Total deaths", 25));
playerItem.AddPanel(statsPanel);
playersCol.AddPlayer(playerItem);
// 3. Populate Details Column
detailsCol.Title = "Match Details";
detailsCol.UpdatePanelPicture("scaleformui", "lobby_panelbackground");
detailsCol.AddItem(new UIFreemodeDetailsItem("Map", "Los Santos"));
detailsCol.AddItem(new UIFreemodeDetailsItem("Time Limit", "10 Minutes"));
Lua
-- 1. Populate Settings Column
local startItem = UIMenuItem.New("Start Match", "Start the match immediately.")
local friendlyFire = UIMenuCheckboxItem.New("Friendly Fire", true, 1, "Toggle friendly fire.")
settingsCol:AddSettings(startItem)
settingsCol:AddSettings(friendlyFire)
-- 2. Populate Players Column
local crew = CrewTag.New("DEV", true, false, CrewHierarchy.Leader, SColor.HUD_Green)
local playerItem = FriendItem.New(GetPlayerName(PlayerId()), SColor.HUD_Green, true, 100, "Ready", crew)
playerItem:SetLeftIcon(LobbyBadgeIcon.IS_PC_PLAYER, false)
playerItem.ClonePed = PlayerPedId()
-- Create a stats panel for the player
local statsPanel = PlayerStatsPanel.New("Player Stats", SColor.HUD_Green)
statsPanel.RankInfo:RankLevel(50)
statsPanel.RankInfo:LowLabel("Rank 50")
statsPanel:AddStat(PlayerStatsPanelStatItem.New("Kills", "Total kills", 75))
statsPanel:AddStat(PlayerStatsPanelStatItem.New("Deaths", "Total deaths", 25))
playerItem:AddPanel(statsPanel)
playersCol:AddPlayer(playerItem)
-- 3. Populate Details Column
detailsCol:Title("Match Details")
detailsCol:UpdatePanelPicture("scaleformui", "lobby_panelbackground")
detailsCol:AddItem(UIMenuFreemodeDetailsItem.New("Map", "Los Santos"))
detailsCol:AddItem(UIMenuFreemodeDetailsItem.New("Time Limit", "10 Minutes"))
Step 4: Handle Events and Open the Menu
Handle column selection changes and draw the menu in a tick loop.
C#
// Handle column index changes
settingsCol.OnIndexChanged += (col, index) =>
{
Debug.WriteLine($"Settings column index changed to {index}");
};
playersCol.OnPlayerItemActivated += (col, item) =>
{
// Switch focus to the right column (details/stats panel) when a player is selected
lobbyMenu.SelectColumn(PM_COLUMNS.RIGHT);
};
// Open the menu
lobbyMenu.Visible = true;
// Register the tick loop to draw the menu
BaseScript.RegisterTick(async () =>
{
if (lobbyMenu.Visible)
{
lobbyMenu.Draw();
}
await BaseScript.Delay(0);
});
Lua
-- Handle column index changes
settingsCol.OnIndexChanged = function(index)
print("Settings column index changed to " .. index)
end
playersCol.OnPlayerItemActivated = function(col, item)
-- Switch focus to the right column (details/stats panel) when a player is selected
lobbyMenu:SelectColumn(2) -- 0 = Left, 1 = Center, 2 = Right
end
-- Open the menu
lobbyMenu:Visible(true)
-- Register the tick loop to draw the menu
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
if lobbyMenu:Visible() then
lobbyMenu:Draw()
end
end
end)