Basic HUD Modification
This tutorial shows you how to change the HUD by adding a graphic. Adding a graphic to the HUD isn't that difficult. However, it is recommended that you know your way around the Material Creation process.
Importing the HUD Material
In general, adding graphics to the HUD follows the same procedure as adding any material to Source-based games, so create your graphic at your own discretion. The difference is that we are going to give vtex some extra parameters in the .txt
file accompanying the .tga
.
We will use the following setup as an example.
"UnlitGeneric" { "nomip" "1" "nocompress" "1" "nolod" "1" }
In this case, we are telling vtex...
- $nomip
- Do not make mip-levels for this texture. Simply because you will not be viewing the HUD from varying distances.
- $nocompress
- Do not use compression on this texture. This prevents artifacting in our graphic.
- $nolod
- Do not use lower quality versions of this texture in lower DirectX versions. This is obvious as the difference in performance is marginal.
Once you have the appropriate variables set up, we are now going to run vtex. It is recommended for clarity that you generate your graphics in the /materials/HUD/
directory (if it does not exist, create it).
For the .vmt
, we are going to use the following setup.
"UnlitGeneric" { "$basetexture" "HUD/nameofyourgraphic" "$translucent" "1" "$translucency" "1" "$ignorez" "1" }
With the .vmt
and hence the material completed, all that's left is to change the HUD and add a class. Let's start with the class.
Adding a HUD Element Class
Open up your copy of MSVS. Do a search for class CHud
. You should be able to cycle through a number of files. I recommend you keep all these stock and if you edit, back them up so you can keep them for reference.
All we are trying to do is put a graphic on the screen. In Source, there is a function we have to call in order to get this to happen, called paint
. We are going to need a variable to act as a place holder for our sprite so that we can call it in the game via the paint
function. It would also be nice to be able to turn this on and off, so we are going to learn how to use cvars to control HUD elements in this way.
Here is our example class definition.
#include "hudelement.h"
#include <vgui_controls/Panel.h>
using namespace vgui;
class CHudImport : public CHudElement, public Panel
{
DECLARE_CLASS_SIMPLE( CHudImport, Panel );
public:
CHudImport( const char *pElementName );
void togglePrint();
virtual void OnThink();
protected:
virtual void Paint();
int m_nImport;
};
Drop the above code into hud_import.h
. Remember, the simpler you keep things now, the easier it will be to understand your code later if you have to alter it.
Now, create a new .cpp
file called hud_import.cpp
. Here are the required includes and pre-function statements (top of your .cpp
file):
#include "hud.h"
#include "cbase.h"
#include "hud_import.h"
#include "iclientmode.h"
#include "hud_macros.h"
#include "vgui_controls/controls.h"
#include "vgui/ISurface.h"
#include "tier0/memdbgon.h"
using namespace vgui;
DECLARE_HUDELEMENT( CHudImport );
In order to kick this off we have to load the texture pointer variable. The best place for that is the constructor of the class.
What we are going to do:
- Get the viewport and parent it
- make it invisible, but with alpha 100%
- create a new texture id for our texture/sprite
- connect the id to the texture
- have it show only if you have the suit and if you aren't dead
Here is how it's done.
CHudImport::CHudImport( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudImport" )
{
Panel *pParent = g_pClientMode->GetViewport();
SetParent( pParent );
SetVisible( false );
SetAlpha( 255 );
//AW Create Texture for Looking around
m_nImport = surface()->CreateNewTextureID();
surface()->DrawSetTextureFile( m_nImport, "HUD/import" , true, true);
SetHiddenBits( HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
}
Our graphic starts out invisible, so we have to paint it now. Let's go on to the paint
function. This one, although simpler, has a very important part associated with sizing and spacing to deal with.
void CHudImport::Paint()
{
SetPaintBorderEnabled(false);
surface()->DrawSetTexture( m_nImport );
surface()->DrawTexturedRect( 2, 2, 128, 128 );
}
First, we set the paint border to false.
Next we draw our texture onto our surface. The next line is the important part. You actually define where you put your panel and how large it is in your HudLayout.res
file. This last statement is attached to the image itself. You set its values like this…
surface()->DrawTexturedRect( xspacing , yspacing, xsize, ysize );
You would put your own values in there according to the size of your picture.
There are two steps to go, our cvar toggle as well as editing the HudLayout.res
.
Defining the ConVar
First, let's define the cvar. Go back up to the top of the cpp file and paste this:
static ConVar show_beta("show_beta", "0", 0, "toggles beta icon in upper right corner");
show_beta
is the variable name that we're using as an example. We're actually creating the series of pictures on the second post.
This variable will allow us to type show_beta 1
into the console.
But what will that do for us, we need a function to test it.
void CHudImport::togglePrint()
{
if (!show_beta.GetBool())
this->SetVisible(false);
else
this->SetVisible(true);
}
Not too complex, just a traditional boolean status. And since its something that can change at any time, we should put it into our think function so it is tested always.
void CHudImport::OnThink()
{
togglePrint();
BaseClass::OnThink();
}
And that's it. Build, so we can move onto the .res.
Editing HudLayout.res
Open up /scripts/HudLayout.res
under your mod's main directory and paste the following in it.
HudImport { "fieldName" "HudImport" "xpos" "r86" "ypos" "6" "wide" "80" "tall" "34" "visible" "0" "enabled" "1" "PaintBackgroundType" "2" }
There are a number of settings to choose from. For more information on VGUI schemes, you can read VGUI Documentation#Schemes.
Booting the game now, you should be looking at your HUD, with a graphic in the upper right corner of the screen drawn with rounded corners.
Extra Information
If for some reason you want an animated Texture displaying in the top right hand corner like I Wanted, it is possible and can be achieved. Don't use VtfEdit because when I did it failed to work Use the original method of VTEX. Basically in the text document accompanying the .tgas that you have animated you must specify the start and end frames like this
"startframe" "0" "endframe" "7"
And call that .txt document the same as your .tgas and click and drag it over VTEX and let it work (NOTE~ you must have the .txt file and .tgas in the materialsrc folder of your sourcesdkcontent/SOURCEMOD/ folder for VTEX to work)
(NOTE~ you can check that it works in VTFEDIT if you open it there and press play, but dont save it there!!!) So when you have your Animated VTF working put it in your SourceMod /materials folder Now create a vmt which is basically a Txt document (you can make them in Notepad but make sure the extension is .vmt) Paste the following code into your .vmt
"UnlitGeneric" { "$basetexture" "'''hud/NameOfYourImage'''" "$translucent" "1" "Proxies" { "AnimatedTexture" { "animatedtexturevar" "$basetexture" "animatedtextureframenumvar" "$frame" "animatedtextureframerate" 10 } } }
Above hud refers to the folder inside your materials folder the VTF is located and NameOfYourImage refers to the name of your VTF (NOTE~ your vmt must be named exactly the same as your VTF e.g = image.vtf and image.vmt) And that covers my explanation as to how to add animated textures to the hud ingame Below please find a link of my animated devilsTrap.vtf inaction