protected override MenuScreen ProtectedUpdate(MenuScreen.ScreenLayout layout)
    {
        DrawTitleString("Choose a game-type and level:", layout.Title);

        #region Draw matches and levels.

        //Some layout data.

        Rect body = layout.Body;

        float sSubtitleYOffset = body.height * Consts.Settings_SubtitleYOffset,
              sSubtitleHeight  = body.height * Consts.Settings_SubtitleHeight;

        float   sListYOffset    = body.height * Consts.Settings_List_YOffset;
        float   sListXOffset    = body.width * Consts.Settings_List_XOffset;
        float   sListSpacing    = body.height * Consts.Settings_List_Spacing;
        Vector2 sListButtonSize = new Vector2(body.width * Consts.Settings_List_ButtonSize.x, body.height * Consts.Settings_List_ButtonSize.y);

        float sTooltipXOffset = body.width * Consts.Settings_TooltipXOffset,
              sTooltipYOffset = body.height * Consts.Settings_TooltipYOffset,
              sTooltipWidth   = body.width * Consts.Settings_TooltipWidth;

        //Some layout rectangles.

        Rect matchesSubtitleRect = new Rect(body.xMin + sListXOffset, body.yMin + sSubtitleYOffset, sListButtonSize.x, sSubtitleHeight),
             levelsSubtitleRect  = new Rect(body.xMax - sListXOffset - sListButtonSize.x, matchesSubtitleRect.yMin, matchesSubtitleRect.width, matchesSubtitleRect.height);

        MyGUI.RadioButtonsLayout matchesLayout = Consts.Settings_List_Layout(new Vector2(matchesSubtitleRect.xMin, matchesSubtitleRect.yMax + sListYOffset), body),
                                 levelsLayout  = Consts.Settings_List_Layout(new Vector2(levelsSubtitleRect.xMin, levelsSubtitleRect.yMax + sListYOffset), body);

        Rect tooltipRect = new Rect(matchesSubtitleRect.xMax + sTooltipXOffset,
                                    body.yMin + sTooltipYOffset,
                                    sTooltipWidth,
                                    body.height - sTooltipYOffset);


        //Display the matches.
        if (matches == null)
        {
            GUI.color = Color.black;
            GUI.Label(body, "XML error when reading match settings:\n\"" + matchSettings.ErrorMessage + "\".");
        }
        else
        {
            GUI.Label(matchesSubtitleRect, "Game-types", WorldConstants.GUIStyles.SubtitleLabels);

            selectedMatchIndex = MyGUI.RadioButtons(matches, selectedMatchIndex, matchesLayout, false, WorldConstants.GUIStyles.SettingsRadioButtons);
            selectedMatch      = matches[selectedMatchIndex].text;

            MatchData.MatchSettings = matchSets[selectedMatchIndex];
        }

        //Display the levels.
        if (levels == null)
        {
            GUI.color = Color.black;
            GUI.Label(body, "XML error when reading level settings:\n\"" + levelGeneration.ErrorMessage + "\".");
        }
        else
        {
            GUI.Label(levelsSubtitleRect, "Levels", WorldConstants.GUIStyles.SubtitleLabels);

            int old = selectedLevelGenIndex;
            selectedLevelGenIndex = MyGUI.RadioButtons(levels, selectedLevelGenIndex, levelsLayout, false, WorldConstants.GUIStyles.SettingsRadioButtons);
            selectedLevelGen      = levels[selectedLevelGenIndex].text;
            if (selectedLevelGen == "Open")
            {
                MatchStartData.IsGeneratingOpen = true;
            }
            else
            {
                MatchStartData.IsGeneratingOpen = false;
            }

            if (old != selectedLevelGenIndex)
            {
                MatchData.GeneratedLevel = levelGens[selectedLevelGenIndex];
                MatchData.GenerateLevelAndSpawns();
            }
        }

        GUI.color = Color.white;
        GUI.Label(tooltipRect, GUI.tooltip, WorldConstants.GUIStyles.SettingsTooltip);

        #endregion

        return(DrawButtonMenu(layout.ButtonMenu,
                              new GUIContent[]
        {
            new GUIContent("Back"),
            new GUIContent("Continue")
        },
                              new GetData <MenuScreen>[]
        {
            () => new MainMenuScreen(MatchData, Consts, Owner),
            () => new LobbyMenuScreen(MatchData, Consts, Owner)
        },
                              this));
    }
    //public override MenuScreen Update()
    //{
    //    //If the players don't need to confirm merging teams, do the normal display.
    //    if (!confirmMergeTeams)
    //    {
    //        //Button layout.

    //        Rect button = new Rect(Screen.width * Consts.Lobby_ButtonsXBorder, Screen.height * (1.0f - Consts.Lobby_ButtonsYBorder),
    //                               Screen.width * 0.5f * (1.0f - Consts.Lobby_ButtonsXBorder - Consts.Lobby_ButtonsXBorder - Consts.Lobby_ButtonsSpacing),
    //                               Screen.height * (1.0f - Consts.Lobby_PlayersHeight - Consts.Lobby_ButtonsYBorder - Consts.Lobby_ButtonsYBorder));

    //        //"Back" and "Next" buttons.
    //        if (GUI.Button(button, "Back to Level/Match Selection"))
    //        {
    //            return new CreateMatchMenuScreen(MatchData, Consts, Owner);
    //        }
    //        button.x += button.width + (Screen.width * Consts.Lobby_ButtonsSpacing);
    //        if (GUI.Button(button, "Generate the Level"))
    //        {
    //            //Try to build the match data.
    //            if (TryBuildMatchData(true))
    //            {
    //                advance = true;
    //                return this;
    //            }
    //            else
    //            {
    //                confirmMergeTeams = true;
    //                nextScreen = null;
    //                return this;
    //            }
    //        }

    //        //Players.
    //        for (int i = 0; i < 4; ++i)
    //        {
    //            playerDatas[i] = PlayerGUI(i, playerDatas[i]);
    //        }
    //    }
    //    //Otherwise, show the confirmation window.
    //    else
    //    {
    //        Vector2 sWndSize = new Vector2(Screen.width * Consts.Lobby_MergeTeamWarning_WindowSize.x, Screen.height * Consts.Lobby_MergeTeamWarning_WindowSize.y);
    //        Vector2 sWndPos = (new Vector2(Screen.width, Screen.height) - sWndSize) * 0.5f;

    //        Rect windBounds = new Rect(sWndPos.x, sWndPos.y, sWndSize.x, sWndSize.y);
    //        GUI.Window(1, windBounds, MergeTeamsWarningWindow, "Team merge warning");
    //    }
    //    return this;
    //}

    /// <summary>
    /// Given a player and his spot on the lobby screen (0-3), displays the GUI layout for his information.
    /// </summary>
    /// <param name="data">The data for the player to be drawn, or "null" if the player hasn't joined.</param>
    /// <returns>The given "data" (possibly with some of its memebers changed), or "null" if the player is no longer in the lobby (or never was).</returns>
    private PlayerData PlayerGUI(int screenIndex, PlayerData data)
    {
        #region Laying out the spaces

        float height = Consts.Lobby_PlayersHeight;
        height -= Consts.Lobby_PlayersYBorder;
        height -= 3.0f * Consts.Lobby_PlayersSpacing;
        height *= 0.25f;

        Rect box = new Rect(Screen.width * Consts.Lobby_PlayersXBorder,
                            (Screen.height * (Consts.Lobby_PlayersYBorder + (screenIndex * (height + Consts.Lobby_PlayersSpacing)))),
                            Screen.width * (1.0f - Consts.Lobby_PlayersXBorder - Consts.Lobby_PlayersXBorder),
                            height * Screen.height);

        Rect characterImage = new Rect(box.xMin + (Screen.width * Consts.Lobby_PlayerBox_ImageXBorder),
                                       box.center.y - (0.5f * Owner.PlayerTexture.height * Consts.Lobby_PlayerBox_ImageScale),
                                       Owner.PlayerTexture.width * Consts.Lobby_PlayerBox_ImageScale,
                                       Owner.PlayerTexture.height * Consts.Lobby_PlayerBox_ImageScale);

        MyGUI.SelectorLayout controlsLayout = new MyGUI.SelectorLayout(new Vector2(Screen.width * Consts.Lobby_PlayerBox_ControlsSelectionXOffsetFromCenter,
                                                                                   box.center.y),
                                                                       Consts.Lobby_PlayerBox_ControlsSelectionSpacing * Screen.width,
                                                                       Owner.LeftArrowTexture.width, Owner.LeftArrowTexture.height,
                                                                       Owner.ControlsTextures[0].width, Owner.ControlsTextures[0].height);

        MyGUI.RadioButtonsLayout teamOptions = new MyGUI.RadioButtonsLayout(new Vector2(box.center.x + (Screen.width * Consts.Lobby_PlayerBox_TeamChoiceXOffsetFromCenter),
                                                                                        box.yMin + (Screen.height * Consts.Lobby_PlayerBox_TeamChoiceYOffset)),
                                                                            new Vector2(Screen.width * Consts.Lobby_PlayerBox_TeamChoiceButtonWidth,
                                                                                        Screen.height * Consts.Lobby_PlayerBox_TeamChoiceButtonHeight),
                                                                            new Vector2(0.0f, Screen.height * Consts.Lobby_PlayerBox_TeamChoiceSpacing), 1);

        MyGUI.RGBLayout makeTeamSliders = Consts.Lobby_PlayerBox_TeamChoiceRGBLayout;
        makeTeamSliders.ScreenPos = new Vector2((teamOptions.TopLeftChoicePos.x / Screen.width) + Consts.Lobby_PlayerBox_TeamChoiceRGBOffset.x,
                                                (teamOptions.TopLeftChoicePos.y / Screen.height) + Consts.Lobby_PlayerBox_TeamChoiceRGBOffset.y);

        Vector2 allySelectorPos = teamOptions.GetOptionPos(1);
        allySelectorPos.y += 0.5f * teamOptions.ButtonSize.y;
        allySelectorPos.x += (Screen.width * Consts.Lobby_PlayerBox_TeamChoiceAllySelectionOffset.x);
        allySelectorPos.y += (Screen.height * Consts.Lobby_PlayerBox_TeamChoiceAllySelectionOffset.y);
        MyGUI.SelectorLayout chooseAllySelector = new MyGUI.SelectorLayout(allySelectorPos,
                                                                           Screen.width * Consts.Lobby_PlayerBox_TeamChoiceAllySelectionSpacing,
                                                                           Owner.LeftArrowTexture.width, Owner.LeftArrowTexture.height,
                                                                           Consts.Lobby_PlayerBox_TeamChoiceAllySelectionChoiceSize.x,
                                                                           Consts.Lobby_PlayerBox_TeamChoiceAllySelectionChoiceSize.y);

        Rect playerLeaveButton = new Rect(box.xMax - (Screen.width * Consts.Lobby_PlayerBox_PlayerLeaveLobbyOffset.x) - Owner.XTexture.width,
                                          box.yMin + (Screen.height * Consts.Lobby_PlayerBox_PlayerLeaveLobbyOffset.y),
                                          Owner.XTexture.width, Owner.XTexture.height);

        Rect clickToJoinButton = new Rect(box.xMin + (Screen.width * Consts.Lobby_PlayerBox_ClickToJoinOffset.x),
                                          box.yMin + (Screen.height * Consts.Lobby_PlayerBox_ClickToJoinOffset.y),
                                          Screen.width * Consts.Lobby_PlayerBox_ClickToJoinSize.x,
                                          Screen.height * Consts.Lobby_PlayerBox_ClickToJoinSize.y);

        #endregion

        //Background box.
        GUI.backgroundColor = Color.white;
        GUI.color           = Color.white;
        GUI.Box(box, "", WorldConstants.GUIStyles.LobbyPlayerBox);

        //Draw player-specific stuff.
        if (data != null)
        {
            //Image.
            GUI.color = data.TeamCol;
            GUI.DrawTexture(characterImage, Owner.PlayerTexture);

            //Control scheme.
            GUI.color          = Color.white;
            data.ControlScheme = (byte)MyGUI.Selector(new GUIContent(Owner.LeftArrowTexture),
                                                      new GUIContent(Owner.RightArrowTexture),
                                                      controlContents, data.ControlScheme, controlsLayout,
                                                      true, true, false,
                                                      WorldConstants.GUIStyles.SelectionsArrows, WorldConstants.GUIStyles.SelectionsSelection);

            //Team/ally selection. Only allow ally selection if at least one other player owns a team.
            GUI.color = Color.white;
            int result = -1;
            if (data.MadeTeam &&
                playerDatas.Where((dat, index) => (dat != null && dat.MadeTeam)).Count() == 1)
            {
                result = 0;
            }
            else
            {
                result = MyGUI.RadioButtons(new GUIContent[2] {
                    new GUIContent("Make new team"), new GUIContent("Ally with player")
                },
                                            (data.MadeTeam ? 0 : 1), teamOptions, false,
                                            WorldConstants.GUIStyles.SettingsRadioButtons);
            }

            //Options for team/ally selection.
            switch (result)
            {
                #region RGB team selection

            case 0:

                //Make a new team if this player didn't already have his own team.
                if (!data.MadeTeam)
                {
                    data.MakeOwnTeam();
                }

                //Do the RGB slider to select a team color.
                data.ChangeOwnTeamColor(MyGUI.RGBSlider(data.TeamCol, makeTeamSliders, true));

                break;

                #endregion

                #region Ally selection

            case 1:

                //Set the ally if this player didn't already have an ally.
                PlayerData pd;
                if (data.MadeTeam)
                {
                    Func <PlayerData, bool> pred = (dat) =>
                    {
                        bool b1 = dat != null;
                        bool b2 = dat != data;
                        bool b3 = (b1 && dat.MadeTeam);
                        return(b1 && b2 && b3);
                    };
                    pd = playerDatas.First(pred);
                    data.JoinOtherPlayer(pd);
                }

                //Get the list of potential allies, and find the current ally.
                List <GUIContent> potentialAlliesContent = new List <GUIContent>();
                List <int>        potentialAlliesIndex   = new List <int>();
                int currentAlly = -1;
                for (int i = 0; i < playerDatas.Length; ++i)
                {
                    if (playerDatas[i] != null && playerDatas[i] != data)
                    {
                        //Prevent infinite loops of alliances by only allowing alliances with team owners.
                        if (playerDatas[i].MadeTeam)
                        {
                            potentialAlliesContent.Add(new GUIContent("Player " + (i + 1).ToString()));
                            potentialAlliesIndex.Add(i);
                        }
                        if (playerDatas[i] == data.Ally)
                        {
                            currentAlly = potentialAlliesIndex.Count - 1;
                        }
                    }
                }

                int selectedAlly = -1;
                try
                {
                    selectedAlly = MyGUI.Selector(new GUIContent(Owner.LeftArrowTexture), new GUIContent(Owner.RightArrowTexture),
                                                  potentialAlliesContent.ToArray(),
                                                  currentAlly,
                                                  chooseAllySelector, true, true, false,
                                                  WorldConstants.GUIStyles.SelectionsArrows, WorldConstants.GUIStyles.SelectionsSelection);
                    data.JoinOtherPlayer(playerDatas[potentialAlliesIndex[selectedAlly]]);
                }
                catch { Debug.Log("Invalid ally! 'currentAlly' = " + currentAlly + ", 'selectedAlly' = " + selectedAlly); }
                break;

                #endregion

            default: throw new InvalidOperationException();
            }

            GUI.color = Color.white;

            //Leaving the lobby. Only allow it if:
            //	1) There are more than the minimum number of players needed for a game.
            //  2) Nobody is allied to this player.
            if (playersInLobby > 2 && playerDatas.All(dat => (dat == null || dat == data || dat.Ally != data)))
            {
                if (GUI.Button(playerLeaveButton, Owner.XTexture))
                {
                    return(null);
                }
            }
        }
        //Otherwise, invite the player to join the lobby.
        else
        {
            if (GUI.Button(clickToJoinButton, "Click here to join the lobby", WorldConstants.GUIStyles.SettingsRadioButtons))
            {
                return(new PlayerData(GetUnusedControlScheme()));
            }
        }

        return(data);
    }