1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Tutorial General GSC Coding: How to create a basic menu base

Discussion in 'Tutorial Section' started by P!X, Jan 25, 2016.

  1. P!X

    P!X Moderator Staff Member

    132
    298
    163
    Credits:
    827
    Since everyone is using the same menu bases i thought im going to try to explain as good as i can how to make your own :grinning:
    This Tutorial hopefully will show you how a basic menu base is working ,if not im sorry.

    Sooo im going to show you how to create a menu base with Menu Text,Menu Title,Background Shader,Scrollbar,Sub Menus and without Verifycation System or Player Menu!
    I also show you how to do it with and without \n Fix.


    Little Info: you dont have to code it like i do there are millions of ways to code best thing is to play around with some basic menu bases,learn from them and then try to find the best way for you to code :grinning:

    There are alot of ways to create a menu base but this is how i learned it and i hope you are able to learn something from this :smile:
    Im sorry if you are not able to understand some things cause my english is not the best and im also not very good at explaining :disappointed:
    But i tried my best and its also my first tutorial ever.


    Steps:
    Code:
    1.)How to Start
    2.)Button Handling Start
    3.)Menu Structure
    4.)Menu Hud(Background,Scrollbar,Menu Title)
    5.)Menu Loading + Menu Text
    6.)Cursor Update + Scrollbar Position
    7.)Button Handling Finish
    


    1.)How to Start
    This is how our script should look like when we are starting
    Code:
    #include maps\mp\_utility;
    #include common_scripts\utility;
    #include maps\mp\gametypes\_hud_util;
    #include maps\mp\gametypes\_hud_message;
    
    init()
    {
        level thread onPlayerConnect();
    }
    onPlayerConnect()
    {
        for(;;)
        {
            level waittill("connected", player);
            player thread onPlayerSpawned();
        }
    }
    onPlayerSpawned()
    {
        self endon("disconnect");
        level endon("game_ended");
        for(;;)
        {
            self waittill("spawned_player");
        }
    }
    
    This are Functions we will need for creating Text Elems and Shader Elems
    Just add them somewhere in your script
    Code:
    createText(font, fontscale, align, relative, x, y, sort, color, alpha, glowColor, glowAlpha, text)
    {
        textElem = CreateFontString( font, fontscale );
        textElem setPoint( align, relative, x, y );
        textElem.sort = sort;
        textElem.type = "text";
        textElem setText(text);
        textElem.color = color;
        textElem.alpha = alpha;
        textElem.glowColor = glowColor;
        textElem.glowAlpha = glowAlpha;
        textElem.hideWhenInMenu = true;
        return textElem;
    }
    createRectangle(align, relative, x, y, width, height, color, alpha, sorting, shadero)
    {
        barElemBG = newClientHudElem( self );
        barElemBG.elemType = "bar";
        if ( !level.splitScreen )
        {
            barElemBG.x = -2;
            barElemBG.y = -2;
        }
        barElemBG.width = width;
        barElemBG.height = height;
        barElemBG.align = align;
        barElemBG.relative = relative;
        barElemBG.xOffset = 0;
        barElemBG.yOffset = 0;
        barElemBG.children = [];
        barElemBG.color = color;
        if(isDefined(alpha))
            barElemBG.alpha = alpha;
        else
            barElemBG.alpha = 1;
        barElemBG setShader( shadero, width , height );
        barElemBG.hidden = false;
        barElemBG.sort = sorting;
        barElemBG setPoint(align,relative,x,y);
        return barElemBG;
    }
    
    Ok now we are going to create the starting function for the base
    lets call the function initMenu
    self.Menu = spawnStruct(); = We are going to store all menu things with this like the current opened submenu or the menu texts
    self.Hud = spawnStruct(); = We are going to store all Menu Hud stuff with this
    self.Menu.Opened = false; = A bool if its true thats means the menu is opened if its false it means the menu is closed
    Code:
    initMenu()
    {
        self.Menu = spawnStruct();
        self.Hud = spawnStruct();
        self.Menu.Opened = false;
    }
    
    So Now we are going to thread the initMenu function from onPlayerConnect like that
    Code:
    onPlayerConnect()
    {
        for(;;)
        {
            level waittill("connected", player);
            player thread onPlayerSpawned();
            if(player isHost())
            {
                player thread initMenu();
            }
        }
    }
    

    2.)Button Handling Start
    Now we are going to create the Button Handling so again create a function lets call it menuButtons with a for loop in it
    this function is threaded from the initMenu() function
    Code:
    menuButtons()
    {
        self endon("disconnect");
        for(;;)
        {
            wait 0.05;
        }
    }
    
    Now add buttons to it using if statements
    Code:
    menuButtons()
    {
        self endon("disconnect");
        for(;;)
        {
            if(self FragButtonPressed())
            {
                wait .3;
            }
            if(self AdsButtonPressed())
            {
                wait .1;
            }
            if(self AttackButtonPressed())
            {
                wait .1;
            }
            if(self UseButtonPressed())
            {
                wait .3;
            }
            if(self MeleeButtonPressed())
            {
                wait .3;
            }
            wait 0.05;
        }
    }
    
    Dont forget to add a little wait at the end of the for loop cause if you dont add that your menu will crash
    Also add a wait for every button cause that makes the menu easier to use :grinning:

    Ok now you have to add your menu opened bool to the buttons to make it so that some buttons only work when the menu is opened or closed
    Code:
    menuButtons()
    {
        self endon("disconnect");
        for(;;)
        {
            if(self FragButtonPressed() && self.Menu.Opened==false)
            {
                wait .3;
            }
            if(self AdsButtonPressed() && self.Menu.Opened==true)
            {
                wait .1;
            }
            if(self AttackButtonPressed()&& self.Menu.Opened==true)
            {
                wait .1;
            }
            if(self UseButtonPressed()&& self.Menu.Opened==true)
            {
                wait .3;
            }
            if(self MeleeButtonPressed()&& self.Menu.Opened==true)
            {
                wait .3;
            }
            wait 0.05;
        }
    }
    
    So now we have a button handling that does nothing atm xD

    3.)Menu Structure
    The Menu Structure is where you add all your sub menus and options

    We are going to create a simple function like this
    This functions is threaded on initMenu()
    Code:
    menuStructure()
    {
    }
    
    We also will need two other functions for this

    Function to create a menu
    self.Menu.title[menu] = title; = Used to store the Menu Title
    self.Menu.parent[menu] = parent; = Used to Store the Menu Parent so the menu knows what to do when the Back button is pressed
    Code:
    CreateMenu(menu,title,parent)
    {
        self.Menu.title[menu] = title;
        self.Menu.parent[menu] = parent;
    }
    
    and a function to create options
    Code:
    addOption(menu,index,text,func,input)
    {
        self.Menu.Text[menu][index] = text;
        self.Menu.Func[menu][index] = func;
        self.Menu.Input[menu][index] = input;
    }
    
    Also add this somewhere in your script its just a test function
    Code:
    Test()
    {
        self iprintln("^1TEST");
    }
    
    Ok now lets create the Main Menu
    Code:
    menuStructure()
    {
        self CreateMenu("main","Main Menu","Exit");
        self addOption("main",0,"Option 1",::Test,"");
        self addOption("main",1,"Option 2",::Test,"");
        self addOption("main",2,"Option 3",::Test,"");
        self addOption("main",3,"Option 4",::Test,"");
        self addOption("main",4,"Option 5",::Test,"");
        self addOption("main",5,"Option 6",::Test,"");
        self addOption("main",6,"Option 7",::Test,"");
        self addOption("main",7,"Option 8",::Test,"");
        self addOption("main",8,"Option 9",::Test,"");
        self addOption("main",9,"Option 10",::Test,"");
        self addOption("main",10,"Option 11",::Test,"");
        self addOption("main",11,"Option 12",::Test,"");
        self addOption("main",12,"Option 13",::Test,"");
        self addOption("main",13,"Option 14",::Test,"");
        self addOption("main",14,"Option 15",::Test,"");
    }
    
    Sorry i cant explain that better cause of my english :disappointed:

    4.)Menu Hud(Background,Scrollbar,Menu Title)
    We are going to need two functions one to create and one to destroy our menu Hud
    Code:
    createHud()
    {
    }
    destroyHud()
    {
    }
    
    Now we are adding a Background shader,Scrollbar Shader and a Menu Title Text Elems to them
    Code:
    createHud()
    {
        self.Hud.Title = createText("default",2.0,"CENTER","TOP",0,10,0,(1,1,1),1,(0,0,0),0,"");
        self.Hud.Title.foreground = true;
        self.Hud.Background = createRectangle("CENTER","CENTER",0,0,200,1000,(0,0,0),.5,0,"white");
        self.Hud.Scrollbar = createRectangle("CENTER","TOP",0,40,200,20,(0,0,0),1,0,"white");
    }
    destroyHud()
    {
        self.Hud.Title destroy();
        self.Hud.Background destroy();
        self.Hud.Scrollbar destroy();
    }
    
    self.Hud.Title.foreground = true; = Used to make the text always stand in front of the shaders

    5.)Menu Loading + Menu Text
    For that we are going to create another function
    lets call it _loadMenu and add some things to it
    this function also has a input its needed to tell the function what menu to load
    self.Menu.CurrentMenu = menu; = This is used to store the current opened menu
    self.Scroller = 0; = Sets our scroller/Cursor back to 0
    self.Hud.Title setText(self.Menu.title[self.Menu.CurrentMenu]); = Sets the menu title
    Code:
    _loadMenu(menu)
    {
        self.Menu.CurrentMenu = menu;
        self.Scroller = 0;
        self.Hud.Title setText(self.Menu.title[self.Menu.CurrentMenu]);
    }
    
    Ok now we need two functions to create and destroy the menu text
    Without \n Fix
    Code:
    createMenuText()
    {
        for(i=0;i<self.Menu.Text[self.Menu.CurrentMenu].size;i++)
        {
            self.Hud.Text[i] = createText("default",1.5,"CENTER","TOP",0,40+(18*i),0,(1,1,1),1,(0,0,0),0,self.Menu.Text[self.Menu.CurrentMenu][i]);
            self.Hud.Text[i].foreground = true;
        }
    }
    destroyMenuText()
    {
        if(isDefined(self.Hud.Text))
        {
            for(i=0;i<self.Hud.Text.size;i++)
            {
                self.Hud.Text[i] destroy();
            }
        }
    }
    
    With \n Fix
    Code:
    createMenuText()
    {
        string = "";
        for(i=0;i<self.Menu.Text[self.Menu.CurrentMenu].size;i++)
        {
            string += self.Menu.Text[self.Menu.CurrentMenu][i]+"\n";
        }
        self.Hud.Text = createText("default",1.5,"CENTER","TOP",0,40,0,(1,1,1),1,(0,0,0),0,string);
        self.Hud.Text.foreground = true;
    }
    destroyMenuText()
    {
        if(isDefined(self.Hud.Text))
        {
            self.Hud.Text destroy();
        }
    }
    
    Then thread those functions on your _loadMenu function like this
    Code:
    _loadMenu(menu)
    {
        self destroyMenuText();
        self.Menu.CurrentMenu = menu;
        self.Scroller = 0;
        self.Hud.Title setText(self.Menu.title[self.Menu.CurrentMenu]);
        self createMenuText();
    }
    

    6.)Cursor Update + Scrollbar Position
    Now Create a function called _scrollUpdate or something else
    Code:
    _scrollUpdate()
    {
    }
    
    Now use if statements to make it so if the scroller is smaller then 0 then set the scroller to the amount of menu text/options in the current menu.
    And also if the scroller is bigger then the amount of menu text/options in the current menu set it to 0
    Code:
    _scrollUpdate()
    {
        if(self.Scroller<0)
        {
            self.Scroller = self.Menu.Text[self.Menu.CurrentMenu].size-1;
        }
        if(self.Scroller>self.Menu.Text[self.Menu.CurrentMenu].size-1)
        {
            self.Scroller = 0;
        }
    }
    
    So now we need something that makes the scrollbar move
    it works like that
    self.Hud.Scrollbar.y = SpawnPosition+(SpaceBetweenTexts*self.Scroller);
    this should look like that
    Code:
    _scrollUpdate()
    {
        if(self.Scroller<0)
        {
            self.Scroller = self.Menu.Text[self.Menu.CurrentMenu].size-1;
        }
        if(self.Scroller>self.Menu.Text[self.Menu.CurrentMenu].size-1)
        {
            self.Scroller = 0;
        }
        self.Hud.Scrollbar.y = 40+(18*self.Scroller);
    }
    
    After that we are going to update our _loadMenu function again
    Code:
    _loadMenu(menu)
    {
        self destroyMenuText();
        self.Menu.CurrentMenu = menu;
        self.Scroller = 0;
        self.Hud.Title setText(self.Menu.title[self.Menu.CurrentMenu]);
        self createMenuText();
            self _scrollUpdate();
    }
    

    7.)Button Handling Finish
    We are going to start with our Open Menu Button
    We are going to add:
    Set Menu Opened bool to true
    Freeze User
    Create the Hud
    and load the Main Menu
    Code:
    if(self FragButtonPressed() && self.Menu.Opened==false)
    {
        self.Menu.Opened = true;
        self freezeControls(true);
        self thread createHud();
        self _loadMenu("main");
        wait .3;
    }
    
    Now the scrolling Buttons(Aim and Attack)
    Code:
    if(self AdsButtonPressed() && self.Menu.Opened==true)
    {
        self.Scroller --;
        self _scrollUpdate();
        wait .1;
    }
    if(self AttackButtonPressed() && self.Menu.Opened==true)
    {
        self.Scroller ++;
        self _scrollUpdate();
        wait .1;
    }
    
    Select Button
    Function of Current Selected Option = self.Menu.Func[menu][scroller/cursor]
    Input of Current Selected Option = self.Menu.Input[menu][scroller/cursor]
    self thread [[Function of Current Selected Option]](Input of Current Selected Option);
    Code:
    if(self UseButtonPressed() && self.Menu.Opened==true)
    {
        self thread [[self.Menu.Func[self.Menu.CurrentMenu][self.Scroller]]](self.Menu.Input[self.Menu.CurrentMenu][self.Scroller]);
        wait .3;
    }
    
    a little example to make it easier to understand
    Code:
    doIt()
    {
        self MainFunction(::printSomething,"Hello");
    }
    MainFunction(function,input)
    {
        self thread [[function]](input);
    }
    printSomething(text)
    {
        self iprintln(text);
    }
    
    Back/Exit Button
    when the parent of your current opened sub menu is Exit then close the menu if not then load the parent of the current opened sub menu
    Code:
    if(self MeleeButtonPressed() && self.Menu.Opened==true)
    {
        if(self.Menu.parent[self.Menu.CurrentMenu]=="Exit")
        {
            self.Menu.Opened = false;
            self freezeControls(false);
            self thread destroyMenuText();
            self thread destroyHud();
        }
        else
        {
            self _loadMenu(self.Menu.parent[self.Menu.CurrentMenu]);
        }
        wait .3;
    }
    

    Extra: How to add a submenu
    Code:
    menuStructure()
    {
        self CreateMenu("main","Main Menu","Exit");
        self addOption("main",0,"Open Sub Menu",::_loadMenu,"sub");
        self addOption("main",1,"Option 2",::Test,"");
        self addOption("main",2,"Option 3",::Test,"");
        self addOption("main",3,"Option 4",::Test,"");
        self addOption("main",4,"Option 5",::Test,"");
        self addOption("main",5,"Option 6",::Test,"");
        self addOption("main",6,"Option 7",::Test,"");
        self addOption("main",7,"Option 8",::Test,"");
        self addOption("main",8,"Option 9",::Test,"");
        self addOption("main",9,"Option 10",::Test,"");
        self addOption("main",10,"Option 11",::Test,"");
        self addOption("main",11,"Option 12",::Test,"");
        self addOption("main",12,"Option 13",::Test,"");
        self addOption("main",13,"Option 14",::Test,"");
        self addOption("main",14,"Option 15",::Test,"");
    
    
        self CreateMenu("sub","Sub Menu","main");
        self addOption("sub",0,"Sub Menu Option 1",::Test,"");
        self addOption("sub",1,"Sub Menu Option 2",::Test,"");
        self addOption("sub",2,"Sub Menu Option 3",::Test,"");
        self addOption("sub",3,"Sub Menu Option 4",::Test,"");
        self addOption("sub",4,"Sub Menu Option 5",::Test,"");
    }
    

    This is how it should look like when you are finished: Please login or register to view links or downloads!
    [​IMG]
     
    Last edited: Feb 14, 2016
  2. God

    God Skiddy

    339
    230
    143
    Credits:
    572
    Very good and helpful thread :grinning:
     
    P!X likes this.
  3. CabCon

    CabCon Head Administrator Staff Member

    3,008
    1,807
    263
    Credits:
    57,148
    Very nice tutorial :smile: I will look to merge the posts :smile: In one :smile:
     
    VerTical likes this.
  4. BaDSooD

    BaDSooD Old CCM Member

    617
    358
    163
    Credits:
    66
    Thank's for the realy nice tutorial, this his has helped me to fix bugs on my menu :tongueclosed:
     
    P!X likes this.
  5. SynixMods

    SynixMods Member

    10
    0
    1
    Credits:
    1
    Hey man how do you change the size and location for both the background and text?
     
  6. BaDSooD

    BaDSooD Old CCM Member

    617
    358
    163
    Credits:
    66
    With this :
    self.Hud.Background = createRectangle("CENTER","CENTER",0,0,200,1000,(0,0,0),.5,0,"white");
    self.Hud.Scrollbar = createRectangle("CENTER","TOP",0,40,200,20,(0,0,0),1,0,"white");
     
  7. SynixMods

    SynixMods Member

    10
    0
    1
    Credits:
    1
    Okay how would I use that with this menu? Please login or register to view links or downloads!
     
  8. BaDSooD

    BaDSooD Old CCM Member

    617
    358
    163
    Credits:
    66
    Contact me on PM, say me all you want to change and I give you all the help you need to finish what you have started / modification of the menu shaders
     
    P!X likes this.
  9. Struck

    Struck New Member

    1
    1
    1
    Credits:
    0
    Which one of the values in any of these steps represents my background opacity? I just want to change it
     
    Syndicate likes this.
  10. Syndicate

    Syndicate Modder

    650
    584
    203
    Credits:
    1,882
    sweet tutorial! A SPRX tutorial would be cool! :grinning:
     
  11. VerTical

    VerTical Head Member Donator

    838
    1,128
    243
    Credits:
    2,431
    Nice Tutorial :grinning:
     
    CabCon likes this.

Share This Page