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

P!X

Moderator
Staff member
Head Staff Team
Messages
342
Points
453
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 :smile:
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 :smile:

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 :grinning:
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 :smile:

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:
You have to be logged in to view links Log in or register now.

 
Last edited:

God

Skiddy
Messages
341
Points
393
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:
You have to be logged in to view links Log in or register now.

Very good and helpful thread :smile:
 
  • Like
Reactions: P!X

CabCon

Head Administrator
Staff member
Head Staff Team
Messages
4,444
Points
628
Very nice tutorial :grinning: I will look to merge the posts :grinning: In one :grinning:
 

BaDSooD

Old CCM Member
Premium Member
Messages
597
Points
488
Thank's for the realy nice tutorial, this his has helped me to fix bugs on my menu :tongueclosed:
 
  • Like
Reactions: P!X

SynixMods

New Member
Messages
10
Points
1
Hey man how do you change the size and location for both the background and text?
 

BaDSooD

Old CCM Member
Premium Member
Messages
597
Points
488
Hey man how do you change the size and location for both the background and text?
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");
 

Struck

Insane-Known Member
Messages
1
Points
353
Which one of the values in any of these steps represents my background opacity? I just want to change it
 

Christien

Insane-Known Member
Messages
115
Points
378
Perfect tutorial! I can't think of any way you could've done it better! It definitely helps newcomers and new coders learn how to create the basics of a mod menu! +1! :smile:
 

Similar threads


Top