Game Development Community

dev|Pro Game Development Curriculum

Inventory Popup Tutorial

by Tim Newell · 12/15/2001 (9:25 am) · 18 comments

Inventory GUI Tutorial

This tutorial will help you create a Graphical Display of the weapons that the player has on them. (but is very easily modified for all inventory items) To invoke the Gui you press the letter i and press i again to exit it.

Note: This tutorial was done with the latest head version from the CVS.

First you need to create the graphics for all of these components in your favorite graphics program (PSP, PS, etc.)
You will need:
background for the Inventory popup. (I used an almost half transparent green png graphic) - name it InvPanel.png
a 64x64 square for empty inventory slot (I used a simply black png graphic) - name it InvEmpty.png
a 64x64 square for each inventory item you want to display (I used an in game screenshot png graphic of the rifle and the crossbow) name it Inv[insert ingame datablock name here].png - so if it was the rifle's inventory image you would name it InvRifle.png
a20x20 up arrow graphic for scrolling up (I used a simple black arrow) - name it InvUp.png
a20x20 down arrow graphic for scrolling down (I used a simple black arrow) - name it InvDown.png

You need to put all of these png files in a dir called Inv in the C:\GarageGames\torque\example\fps\client\ui directory.

Now it's time to do some coding.

First open the file - C:\GarageGames\torque\example\fps\client\scripts\default.bind.cs Go down to the section:

//------------------------------------------------------------------------------
// Item manipulation
//------------------------------------------------------------------------------

and add the following code:

$InvState = false;

function toggleInventory() {
   if ($InvState == false) {
      commandToServer('DisplayInventory');
      $InvState = true;
   } else {
		Canvas.setContent( PlayGui );
		$InvState = false;
   }

}

moveMap.bindCmd(keyboard, "i", "toggleInventory();", "");

Next open the file - C:\GarageGames\torque\example\fps\client\config.cs and add the following line to the end:

moveMap.bindCmd(keyboard, "i", "toggleInventory();", "");

Next open the file - C:\GarageGames\torque\example\fps\client\init.cs and add after the other Gui exec statements (under // Load up the shell GUIs):

exec("./ui/InventoryGui.gui");

and add after the other script exec statements (under // Client scripts):

exec("./scripts/InventoryGui.cs");


Next open the file - C:\GarageGames\torque\example\fps\client\ui\defaultGameProfiles.cs and add this code to the end:

//-----------------------------------------------------------------------------
// Inventory popup profile

new GuiControlProfile ("InventoryProfile")
{
   opaque = false;
   fillColor = "128 128 128";
   fontColor = "0 0 0";
   border = true;
   borderColor = "0 0 0";
   fontType = "Arial";
   fontSize = 18;
};


Next open the file - C:\GarageGames\torque\example\fps\server\scripts\commands.cs and add this code to the end:

//-----------------------------------------------------------------------------

function serverCmdDisplayInventory(%client)
{
   //Had to use a string hack to get the data to the client since arrays do not seem to
   //work in function passing
   if (%client.player.hasInventory("Rifle"))
        %InvData = "Rifle" @ " " @ %client.player.hasInventory("RifleAmmo") @ " ";
		
   if (%client.player.hasInventory("Crossbow")) {
       %InvData = %InvData @ "Crossbow" @ " " @ %client.player.hasInventory("CrossbowAmmo") @ " ";
   }

   //Send the info to the client to display it   
   commandToClient(%client, 'PopInventory',%InvData);
  
}

***UPDATE***
Sorry i forgot this, you might have been wondering where hasInventory was defined:

Open file C:\GarageGames\head\torque\example\fps\server\scripts\inventory.cs and add the following code to the end:

//-----------------------------------------------------------------------------

function ShapeBase::hasInventory(%this, %data) {
    return %this.inv[%data];
}


***END UPDATE***


Next create a new .cs file (blank text file with a .cs extension) and put it in the dir C:\GarageGames\head\torque\example\fps\client\scripts then add the following code as its contents:

//-------------------------------------------------
// InventoryGui.cs
//-------------------------------------------------

$InvWordCount = 0;
$CurrentBottomSlot = 4;

new ActionMap(InvMap);
    InvMap.bindCmd(keyboard, "i", "toggleInventory();", "");

function InventoryGui::onWake()
{
    InvpName.setText("Inventory for " @ $pref::Player::Name);
    $enableDirectInput = "1";
    activateDirectInput();
    
    InvMap.push();
}

function InventoryGui::onSleep()
{
    InvMap.pop();
}

function clientCmdPopInventory(%InvData) {

    //String Hack since I couldn't get arrays to pass
    $InvWordCount = getWordCount(%InvData);
	
    //reset the Bottom Slot to default
    $CurrentBottomSlot = 4;

    %InvWdCount = 0;
    if ($InvWordCount > 0) {

        for (%i = 0; %i < ($InvWordCount/2); %i++) {
		    $WeaponTokens[%i] = getWord(%InvData,%InvWdCount);
            %InvWdCount++;
            $AmmoTokens[%i] = getWord(%InvData,%InvWdCount);
		    %InvWdCount++;
		}


	}

    if ($InvWordCount > 0) {  //Slot 1
         Slot1.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[0] @ ".png");
		 Slot1Desc.setText($WeaponTokens[0] @ " Ammo: " @ $AmmoTokens[0]);
    } else {
	     Slot1.setBitmap("fps/client/ui/Inv/InvEmpty.png");
         Slot1Desc.setText("Inventory Slot Available");
	}
	
	if ($InvWordCount > 2) {  //Slot 2
         Slot2.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[1] @ ".png");
		 Slot2Desc.setText($WeaponTokens[1] @ " Ammo: " @ $AmmoTokens[1]);
    } else {
	     Slot2.setBitmap("fps/client/ui/Inv/InvEmpty.png");
         Slot2Desc.setText("Inventory Slot Available");
	}

	if ($InvWordCount > 4) {  //Slot 3
         Slot3.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[2] @ ".png");
		 Slot3Desc.setText($WeaponTokens[2] @ " Ammo: " @ $AmmoTokens[2]);
    } else {
         Slot3.setBitmap("fps/client/ui/Inv/InvEmpty.png");
		 Slot3Desc.setText("Inventory Slot Available");
	}

    if ($InvWordCount > 6) {  //Slot 4
         Slot4.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[3] @ ".png");
		 Slot4Desc.setText($WeaponTokens[3] @ " Ammo: " @ $AmmoTokens[3]);
    } else {
	     Slot4.setBitmap("fps/client/ui/Inv/InvEmpty.png");
         Slot4Desc.setText("Inventory Slot Available");
	}
	

    Canvas.setContent( InventoryGui );
}

//--------------------------------------------------------------------
// "Arrow Keys"
//--------------------------------------------------------------------

function UpArrowEvt::onMouseDown(%this, %obj)
{
    if ($InvWordCount > 8 && $CurrentBottomSlot > 4) {
        
		$CurrentBottomSlot--;

        Slot1.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[$CurrentBottomSlot-4] @ ".png");
		Slot1Desc.setText($WeaponTokens[$CurrentBottomSlot-4] @ " Ammo: " @ $AmmoTokens[$CurrentBottomSlot-4]);

        Slot2.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[$CurrentBottomSlot-3] @ ".png");
		Slot2Desc.setText($WeaponTokens[$CurrentBottomSlot-3] @ " Ammo: " @ $AmmoTokens[$CurrentBottomSlot-3]);

        Slot3.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[$CurrentBottomSlot-2] @ ".png");
		Slot3Desc.setText($WeaponTokens[$CurrentBottomSlot-2] @ " Ammo: " @ $AmmoTokens[$CurrentBottomSlot-2]);

        Slot4.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[$CurrentBottomSlot-1] @ ".png");
		Slot4Desc.setText($WeaponTokens[$CurrentBottomSlot-1] @ " Ammo: " @ $AmmoTokens[$CurrentBottomSlot-1]);

	}
}

function DownArrowEvt::onMouseDown(%this, %obj)
{
    if ($InvWordCount > 8 && $CurrentBottomSlot < ($InvWordCount/2)) {

	    $CurrentBottomSlot++;

        Slot1.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[$CurrentBottomSlot-4] @ ".png");
    	Slot1Desc.setText($WeaponTokens[$CurrentBottomSlot-4] @ " Ammo: " @ $AmmoTokens[$CurrentBottomSlot-4]);

        Slot2.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[$CurrentBottomSlot-3] @ ".png");
		Slot2Desc.setText($WeaponTokens[$CurrentBottomSlot-3] @ " Ammo: " @ $AmmoTokens[$CurrentBottomSlot-3]);

        Slot3.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[$CurrentBottomSlot-2] @ ".png");
		Slot3Desc.setText($WeaponTokens[$CurrentBottomSlot-2] @ " Ammo: " @ $AmmoTokens[$CurrentBottomSlot-2]);

        Slot4.setBitmap("fps/client/ui/Inv/Inv" @ $WeaponTokens[$CurrentBottomSlot-1] @ ".png");
		Slot4Desc.setText($WeaponTokens[$CurrentBottomSlot-1] @ " Ammo: " @ $AmmoTokens[$CurrentBottomSlot-1]);

	}
}

Our last thing to do know is create the actual gui so open Torque and go into a map. Then hit F10 to bring up the GUI editor.

In the grey box under the main window beside the New Control dropdown box you should see a button labeled New... Click it.
In the Gui Name field, type InventoryGui and in the Class: drop down box where it says GuiControl click it and choose GameTSCtrl. Then click Create.

Now we need to save our new Gui Script. Now you will see in the bottom dropdown box your script name. (InventoryGui) Beside it click the button labeled Save. Then click the Dropdown box beside Directory and choose fps/client/ui (this way our new script gets saved with all of the other scripts). Make sure the script is named InventoryGui.gui (it should be) then click Save.

Now to complete the rest of the GUI. First lets add the background for the popup. (my green half transparent png) click the drop down New Control and choose GuiBitmapCtrl. Then put in its Name: field InventoryPanel set its horizSizing to relative and its vertSizing to relative, then set its bitmap field to fps/client/ui/Inv/InvPanel.png then click Apply. Now resize it with the mouse to how you want it to look.

Next lets add the text that in game will be displayed as Inventory for PlayerName. Click the drop down New Control and choose GuiTextCtrl. Then put in its Name: field InvpName set its horizSizing to relative and its vertSizing to relative, then set its profile to InventoryProfile then click Apply. Now resize it with the mouse to be across the top of the popup background.

Next it is time to add the 4 empty png items to the left side of the popup background. Click the drop down New Control and choose GuiBitmapCtrl. Then put in its Name: field Slot1 set its horizSizing to relative and its vertSizing to relative, then set its bitmap field to fps/client/ui/Inv/InvEmpty.png then click Apply. Now resize it with the mouse to how you want it to look. Then repeat this step for the other 3, Slot2, Slot3, Slot4.

Next it is time to add the 4 Text Descriptions( to the right side of the 4 empty png items) that will display the weapon name and ammo. Click the drop down New Control and choose GuiTextCtrl. Then put in its Name: field Slot1Desc set its horizSizing to relative and its vertSizing to relative, then set its profile to InventoryProfile then click Apply. Now resize it with the mouse to how you want it to look. Then repeat this step for the other 3, Slot2Desc, Slot3Desc, Slot4Desc.

The last of the GUI to add is the arrow buttons. First we add the 2 pngs for the up arrow and the down arrow on the right side of the popup background. Click the drop down New Control and choose GuiBitmapCtrl. Then put in its Name: field UpArrow set its horizSizing to relative and its vertSizing to relative, then set its bitmap field to fps/client/ui/Inv/InvUp.png then click Apply. Now resize it with the mouse to how you want it to look. Next click the drop down New Control and choose GuiBitmapCtrl. Then put in its Name: field DownArrow set its horizSizing to relative and its vertSizing to relative, then set its bitmap field to fps/client/ui/Inv/InvDown.png then click Apply. Now resize it with the mouse to how you want it to look.
Now to give these "buttons" functionality we need to add a MouseEvt over each one. Click the drop down New Control and choose GuiMouseEventCtrl. Then put in its Name: field UpArrowEvt set its horizSizing to relative and its vertSizing to relative, then click Apply. Now resize and position it over the area that you want the user to click to get the up arrow to work. Next click the drop down New Control and choose GuiMouseEventCtrl. Then put in its Name: field DownArrowEvt set its horizSizing to relative and its vertSizing to relative, then click Apply. Now resize and position it over the area that you want the user to click to get the down arrow to work.

Now click Save again so that all of our changes from the beginning are saved in our new script. After saving, click the dropdown box with InventoryGui in it and select PlayGui then press F10 to exit the GUI editor.

Restarting Torque may be required before the Inventory will work correctly.

#1
12/14/2001 (6:49 am)
Can we say we love you?

Is that allowed here?

:)
#2
12/14/2001 (8:58 am)
I love you! =P

- Is
#3
12/17/2001 (8:53 pm)
Yes, thank you.
#4
12/20/2001 (10:48 pm)
I could not get the %InvData String to get pasted to then clientCmdPopInventory(%InvData) function can you help me with this problem?
#5
12/20/2001 (11:39 pm)
What exactly is your error? Check the console and see if its saying anything is wrong.


Also for anyone who has finished this tutorial(and has access to changing the C++ code) might want to check out the more advanced version of this at: Inventory v2
#6
03/26/2002 (5:32 pm)
O.K I am a complete worthless idiot with this torque GUI stuff ;)

I attempted to follow your HowTo to create the actual GUI.

"Now to complete the rest of the GUI. First lets add the background for the popup. (my green half transparent png) click the drop down New Control and choose GuiBitmapCtrl. Then put in its Name: field InventoryPanel set its horizSizing to relative and its vertSizing to relative, then set its bitmap field to fps/client/ui/Inv/InvPanel.png then click Apply. Now resize it with the mouse to how you want it to look. "

no matter what .png I place in the bitmap field NOTHING SHOWS! all I see is a god green bacground that is from the GameTSCtrl object, I can not see the bitmap of the Panel thus can not place the freaking text box correctly.

Someone please load that .357 and blow my skull to shreds, this is just down right pitiful ;)
#7
03/11/2004 (1:14 am)
I also have this visualization problem...
#8
07/29/2004 (9:05 pm)
REMOVED

No longer need help.
#9
08/24/2004 (9:47 am)
oki great scripting ..... ohh by the way I am a fan .....

by the way the reason that you can't find the pictures is you link wrong ... when Tim wrote this great code the game was the folder was named /fps/ ..... now is it /starter.fps/ so search and replace fps with starter.fps.

and thanks again Tim I will try to go in your steps and make a Inventory where you can change what you have, and where you have it... a small drag and drop.
#10
09/18/2005 (9:14 am)
cant seem to get the bind key to work any ideas? on why this is happening?
#11
03/23/2006 (10:17 pm)
I had the same problem with the bind not working, I must have been missing a cs to delete on top of the dso files. If you go into the console and manually do a bind, then things wil start to, and continue to work just fine.
#12
04/26/2006 (11:42 am)
I can not get the inventory to display I did the maual bind but when I push I it says serverCommandDisplayInventory : Unknown command. Anyone know what the problem is?
#13
08/17/2006 (2:04 pm)
could this be modified to work with the w,a,s,d keys? like to have a grid for teh inventory and pressing a button it would move it over (maybe 2d array?) maybe even have a push() like InvMap that is called when the inventory is activated and and push () moveMap when it is closed?

hmm, i c great potencial!
#14
11/17/2006 (5:39 am)
I am very thankful to Tim Newell for this tutorial.i worked on this tutorial.it is working fine.but it is woking fine for rifle ammo and crossbow ammo .hey i want to add rocket_launcher ammo.can any body help me that in which part of this tutorial should be modified.

again i am thanking to all.
#15
04/25/2007 (1:36 pm)
removed.


great resource saved me tons of time
#16
03/27/2008 (11:39 am)
I keep getting "clientCmdPopInventory: Unknown command." in the console, any ideas?
#17
08/01/2008 (4:28 am)
i use everything but i see it at console

ClientCmdPopİnventory: Unknown Command

HELP PLease :S
#18
08/01/2008 (4:48 am)
no no no no :D im stupid really really stupid :D
@ Robbie
Your Question:
I keep getting "clientCmdPopInventory: Unknown command." in the console, any ideas?

Problem is we forget Add it
exec("./scripts/InventoryGui.cs");
client/scripts/init.cs :)