HUD: Unity 3D OnGUI Remake
Contents
Overview
Code Author: Loken01
For a while I had taken a break from UDK and had been using Unity3D for a bit, and even though it will never quite match up with AutoDesk ScaleForm, I thought I'd give it a whirl at making a more simplistic HUD system for users.
The basics of AHUD I learnt from Rama's awesome tutorials!
Everything in this is based on objects, so everything can handle it's own instance! Makes things super easy for us!
Functions Matching Unity's GUI class
- Labels
- Textures
- Materials
- Animated Materials
- Buttons
- Animated Buttons
- Horizontal Sliders
- Vertical Sliders
- Movable Windows (Coming soon)
Transparency
Everything in this entire HUD system has full control over transparency. Materials are handled in the material editor. Textures work best if their LOD group is set to 'UI'.
Centering
I wanted to make sure everything could be scaled according to screen size so I made four functions:
- Scale Width
- Scale Height
- Center Horizontal
- Center Vertical
These work based on getting the sizes from the Canvas, and then doing a check against the relative position of 1920x1080. It means no matter the screen size, everything will stay exactly the same relative to the edges of the screen.
Input
Currently the only form of input is the mouse. But you can use your PlayerController or Character class to bind other actions and simply tweak this code. My personal version works using the controller and simulating mouse movement, but I wanted to generalize as much as possible for this tutorial.
Demos
So I made a few gifs just to show what could be done in about 2-3 minutes with this HUD system!
Labels:
Buttons:
Animated Buttons:
Horizontal Sliders:
Vertical Sliders:
Credit
Everything I learnt about the standard AHUD system came directly from Rama, so this is like an extension to his work
Apart from a few tiny bits here and there, (Rama's) almost all of this is my own creation.
Also a big thanks to DroseGaming for helping me with some bug issues!
Why Did I make this system?
I wanted it to be easier to make an easy to use object based system that could be easily managed in memory, handle their own animations, etc dynamically, without cluttering up your HUD class.
Pre-requisites
As in Rama's tutorial, you need to have a few things:
Font
Creat a font in your content browser. Right click, and make a new font, and give it a large default size. I tend to just stick it to the highest.
Texture
Literally any texture would do.
Button Material
Create a new material and set it to be Transparent and Unlit. You will need a button 'Up' and button 'Down' texture. You will need two parameters called 'Highlight' and 'Click'
And finally plug everything together like so:
Animated Button Material
This can be done exactly the same as above, but the textures would need to be in a sprite sheet like layout.
Slider Background Material
Create a material that is Transparent and Unlit. Only really needs the one texture.
Slider Button Material
For this you can simply use any "Button Material"
C++ Code
The code below assumes you have created a new class named "YourHud". Although you can rename to whatever you want. Just clean up any references. Simply replace any references to "YourGame.h" to be whatever your game has been called.
HUDObjects.h
153 Lines
#pragma once
#include "GameFramework/HUD.h"
#include "HUDObjects.generated.h"
USTRUCT()
struct FShapeStruct
{
GENERATED_USTRUCT_BODY()
//Vars
float x;
float y;
float w;
float h;
//default properties
FShapeStruct()
{
x = 0;
y = 0;
w = 0;
h = 0;
}
};
UCLASS()
class UHUDObjects : public UObject
{
GENERATED_UCLASS_BODY()
protected:
//State handler
bool IsButton;
//Shape and positioning of this object
FShapeStruct BGShapeAndPos;
//Shape and positioning of this object
FShapeStruct ShapeAndPos;
//Background material reference
UPROPERTY()
UMaterialInterface* BackGround;
//Slider background material reference
UPROPERTY()
UMaterialInterface* SliderBackGround;
//Created material instance reference
UPROPERTY()
UMaterialInstanceDynamic* MIObj;
//Created material instance for a slider background
UPROPERTY()
UMaterialInstanceDynamic* BGMIObj;
//Name of the highlight parameter
FString HighLightName;
//Name of the click parameter
FString ClickName;
//Whether or not this has an animation
bool bHasAnim;
//Scale of the text
float ScaleAmount;
//Text
FString Text;
//Reference to the font used
UPROPERTY()
UFont* Font;
//Animation
FVector2D AnimTiling;
//Number of tiles in total
int NumTiles;
//Time between frame updates
float FrameUpdateDelay;
//Current time taken from the last frame update
float currentTime;
//CurrentAnimTile
int Tile;
float MatU;
float MatV;
float MatUWidth;
float MatVHeight;
float CropU;
float CropV;
float CropX;
float CropY;
UPROPERTY()
UTexture2D* Texture;
//Functions
public:
//State of button
bool IsInside;
bool bGrabbed;
//If the passed position is within the screen bounds of this object
bool Hovered();
//Update and Draw depending on how the object was initialised
//SHOULD BE CALLED WITH CARE
void Update(AHUD* HUDRef, FVector2D MousePos, float x, float y, float w, float h, float Scale, FLinearColor TextColour = FLinearColor::White);
//Draw the horizontal slider
float DrawHorizontalSlider(AHUD* HUDRef, float Amount, float MinAmount, float MaxAmount, FVector2D MousePos, float x, float y, float w, float h, float Scale);
//Draw the vertical slider
float DrawVerticalSlider(AHUD* HUDRef, float Amount, float MinAmount, float MaxAmount, FVector2D MousePos, float x, float y, float w, float h, float Scale);
//Check for click on slider BG
bool CheckInsideSliderBG(FVector2D MousePos);
//Draw the texture that this object was initialised with.
//SHOULD BE CALLED WITH CARE
void DrawTexture(AHUD* HUDRef, float x, float y, float w, float h, FColor pColour);
//Crops the U/V sizes. 0=No crop, 1=MaxCrop
//This will only work on Texture or Animation Objects
void CropObjectUV(FVector2D UVCrop);
//Crops the X/Y sizes. 0=No crop, 1=MaxCrop
//This will only work on Texture or Animation Objects
void CropObjectXY(FVector2D XYCrop);
//Initialise this object with only Text
void Init(FString pText, UFont* pFont);
//Initialise this object with only a texture
void Init(UTexture2D* pTexture);
//Initialise this object with a highlightable material
void Init(bool pIsButton, UMaterialInterface* BackgroundMaterial, FString pHighLightName, FString pClickName);
//Initialise this object with a slider button and background
void Init(bool pIsButton, UMaterialInterface* SliderMaterial, FString pHighLightName, FString pClickName, UMaterialInterface* BackgroundMaterial);
//Initialise this object with a highlightable material with text
void Init(bool pIsButton, UMaterialInterface* BackgroundMaterial, FString pHighLightName, FString pClickName, FString pText, UFont* pFont);
//Initialise this object with a highlightable animated material
void Init(bool pIsButton, UMaterialInterface* BackgroundMaterial, FString pHighLightName, FString pClickName, FVector2D pAnimTiling, int pNumTiles, float pFrameUpdateDelay);
//Initialise this object with a highlightable animated material with text
void Init(bool pIsButton, UMaterialInterface* BackgroundMaterial, FString pHighLightName, FString pClickName, FString pText, UFont* pFont, FVector2D pAnimTiling, int pNumTiles, float pFrameUpdateDelay);
protected:
void UpdateAnim();
void CheckInside(FVector2D MousePos);
};
HUDObjects.cpp
487 Lines
#include "YourGame.h"
#include "HUDObjects.h"
UHUDObjects::UHUDObjects(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
{}
void UHUDObjects::Init(UTexture2D* pTexture)
{
//Pass the texture
Texture = pTexture;
}
void UHUDObjects::Init(bool pIsButton, UMaterialInterface* BackgroundMaterial, FString pHighLightName, FString pClickName)
{
//Initialise global variables with passed parameters
IsButton = pIsButton;
//This material pointer is assigned as another pointer isn't it?
//So how would I make is it's own dynamic instance?
BackGround = BackgroundMaterial;
//Set the highlight and click names
HighLightName = pHighLightName;
ClickName = pClickName;
//If the material exists
if (BackGround != NULL)
{
//Create an instance of it
MIObj = UMaterialInstanceDynamic::Create(BackGround->GetMaterial(), this);
}//if
}//Init
void UHUDObjects::Init(bool pIsButton, UMaterialInterface* SliderMaterial, FString pHighLightName, FString pClickName, UMaterialInterface* BackgroundMaterial)
{
//pass vars
Init(pIsButton, SliderMaterial, pHighLightName, pClickName);
//set slider background
SliderBackGround = BackgroundMaterial;
//if it exists
if (SliderBackGround != NULL)
{
//create an instance of it
BGMIObj = UMaterialInstanceDynamic::Create(SliderBackGround->GetMaterial(), this);
}//if
}//Init
void UHUDObjects::Init(bool pIsButton, UMaterialInterface* BackgroundMaterial, FString pHighLightName, FString pClickName, FVector2D pAnimTiling, int pNumTiles, float pFrameUpdateDelay)
{
//pass vars
Init(pIsButton, BackgroundMaterial, pHighLightName, pClickName);
//set anim tilings
AnimTiling = pAnimTiling;
//set number of anim tiles
NumTiles = pNumTiles;
//set that we have an anim
bHasAnim = true;
//set up frame delay
FrameUpdateDelay = pFrameUpdateDelay;
//set current time to the max
currentTime = FrameUpdateDelay;
//set current tile to 0
Tile = 0;
//calculate the u width of the material
MatUWidth = 1 / AnimTiling.X;
//calculate the v width of the material
MatVHeight = 1 / AnimTiling.Y;
}//Init
void UHUDObjects::Init(bool pIsButton, UMaterialInterface* BackgroundMaterial, FString pHighLightName, FString pClickName, FString pText, UFont* pFont, FVector2D pAnimTiling, int pNumTiles, float pFrameUpdateDelay)
{
//pass vars
Init(pIsButton, BackgroundMaterial, pHighLightName, pClickName, pAnimTiling, pNumTiles, pFrameUpdateDelay);
//set text
Text = pText;
//set font
Font = pFont;
}//Init
void UHUDObjects::Init(FString pText, UFont* pFont)
{
//Initialise global variables with passed parameters
IsButton = false;
Text = pText;
Font = pFont;
}//Init
void UHUDObjects::Init(bool pIsButton, UMaterialInterface* BackgroundMaterial, FString pHighLightName, FString pClickName, FString pText, UFont* pFont)
{
//pass vars
Init(pIsButton, BackgroundMaterial, pHighLightName, pClickName);
//Set text
Text = pText;
//Set font
Font = pFont;
}//Init
void UHUDObjects::CheckInside(FVector2D MousePos)
{
//If within the X area
if (MousePos.X > ShapeAndPos.x && MousePos.X < ShapeAndPos.x + ShapeAndPos.w)
{
//If within the Y area
if (MousePos.Y > ShapeAndPos.y && MousePos.Y < ShapeAndPos.y + ShapeAndPos.h)
{
//Mouse is inside
IsInside = true;
}//if
else
{
//Mouse is not inside
IsInside = false;
}//else
}//if
else
{
//Mouse is not inside
IsInside = false;
}//else
//If the material instance exists and the highlight name exists
if (MIObj != NULL && IsButton && HighLightName.Len() > 0)
{
//Set up var
float TmpVar;
//Get highlight value, to be sure it exists
if (MIObj->GetScalarParameterValue(FName(*HighLightName), TmpVar))
{
//if we are inside
if (IsInside)
{
//set it to 1
MIObj->SetScalarParameterValue(FName(*HighLightName), 1);
}//if
else
{
//otherwise set it to 0
MIObj->SetScalarParameterValue(FName(*HighLightName), 0);
}//else
}//if
}//if
//If the material instance exists and the click name exists
if (MIObj != NULL && IsButton && ClickName.Len() > 0)
{
//Set up var
float TmpVar;
//Get click value, to be sure it exists
if (MIObj->GetScalarParameterValue(FName(*ClickName), TmpVar))
{
//if it has been grabbed
if (bGrabbed)
{
//set it to 1
MIObj->SetScalarParameterValue(FName(*ClickName), 1);
}//if
else
{
//otherwise set it to 0
MIObj->SetScalarParameterValue(FName(*ClickName), 0);
}//else
}//if
}//if
}//CheckInside
bool UHUDObjects::CheckInsideSliderBG(FVector2D MousePos)
{
//If within the X area
if (MousePos.X > BGShapeAndPos.x && MousePos.X < BGShapeAndPos.x + BGShapeAndPos.w)
{
//If within the Y area
if (MousePos.Y >(BGShapeAndPos.y - BGShapeAndPos.h) && MousePos.Y < BGShapeAndPos.y + (BGShapeAndPos.h * 2))
{
//Mouse is inside
return true;
}//if
else
{
//Mouse is not inside
return false;
}//else
}//if
else
{
//Mouse is not inside
return false;
}//else
}
bool UHUDObjects::Hovered()
{
return IsInside;
}//Hovered
void UHUDObjects::UpdateAnim()
{
//if the time is greater than 0
if (currentTime > 0)
{
//decrement it
currentTime -= 0.01f;
}//if
else
{
//otherwise reset it
currentTime = FrameUpdateDelay;
//if the current tile is less than the max number of tiles
if (Tile < (NumTiles - 1))
{
//increment it
Tile += 1;
//increment the u position
MatU += MatUWidth;
//if the u position is now equal to or greater than 1
if (MatU >= 1)
{
//reset it to 0
MatU = 0;
//increment the v position
MatV += MatVHeight;
//if the v position is now equal to or greater than 1
if (MatV >= 1)
{
//reset it
MatV = 0;
}//if
}//if
}//if
else
{
//otherwise reset everything
Tile = 0;
MatU = 0;
MatV = 0;
}//else
}//else
}//UpdateAnim
void UHUDObjects::Update(AHUD* HUDRef, FVector2D MousePos, float x, float y, float w, float h, float Scale, FLinearColor TextColour)
{
//Set vars
ShapeAndPos.x = x;
ShapeAndPos.y = y;
ShapeAndPos.w = w;
ShapeAndPos.h = h;
ScaleAmount = Scale;
//Check if the mouse is inside the object
CheckInside(MousePos);
//If the BG material reference isn't null, and the passed HUD isn't null
if (HUDRef != NULL)
{
if (MIObj != NULL)
{
//if this is an animation
if (bHasAnim)
{
//Update the animation
UpdateAnim();
HUDRef->DrawMaterial(MIObj,
ShapeAndPos.x, ShapeAndPos.y, //X and Y
ShapeAndPos.w - (ShapeAndPos.w * CropX), //Width Minus cropped percentage
ShapeAndPos.h - (ShapeAndPos.h * CropY), //Height Minus cropped percentage
MatU + (MatUWidth * CropX), //U start plus percentage of U Width
MatV + (MatVHeight * CropY), //V start plus percentage of V Height
(MatUWidth * (1 - CropU)) - (MatUWidth * CropX), //Width is percentage of cropped U,
(MatVHeight * (1 - CropV)) - (MatVHeight * CropY), //Height is percentage of cropped V,
1, false); //Other bits
}//if
else
{
//Draw the material as assigned
HUDRef->DrawMaterialSimple(MIObj, ShapeAndPos.x, ShapeAndPos.y, ShapeAndPos.w, ShapeAndPos.h, 1, false);
}//else
}//If
//if the text isn't empty
if (!Text.IsEmpty())
{
//if the font exists
if (Font != NULL)
{
//Get the font text size
float tWidth, tHeight;
HUDRef->GetTextSize(Text, tWidth, tHeight, Font, ScaleAmount);
//Calculate spaceing around the text inside the button
float newX = (ShapeAndPos.w - tWidth) / 2;
float newY = (ShapeAndPos.h - tHeight) / 2;
//Draw text and adjust for center
HUDRef->DrawText(Text, TextColour, ShapeAndPos.x + newX, ShapeAndPos.y + newY, Font, ScaleAmount, false);
}//if
}//if
}//if
}//Update
float UHUDObjects::DrawHorizontalSlider(AHUD* HUDRef, float Amount, float MinAmount, float MaxAmount, FVector2D MousePos, float x, float y, float w, float h, float Scale)
{
//Set vars
BGShapeAndPos.x = x;
BGShapeAndPos.y = y;
BGShapeAndPos.w = w;
BGShapeAndPos.h = h;
ScaleAmount = Scale;
//Work out how much to extend the slider to make it fit correctly
float BGWidener = BGShapeAndPos.w * 0.08f;
//If the BG material reference isn't null, and the passed HUD isn't null
if (HUDRef != NULL)
{
if (BGMIObj != NULL)
{
//Draw the material as assigned
HUDRef->DrawMaterialSimple(BGMIObj, BGShapeAndPos.x - BGWidener, BGShapeAndPos.y, BGShapeAndPos.w + (BGWidener * 2), BGShapeAndPos.h, 1, false);
}//if
}//if
//Get a percentage between 0-1
float PercentageAlong = Amount / (MaxAmount - MinAmount);
//Work out the size/position of the slider, based off of the total size
ShapeAndPos.w = BGShapeAndPos.w*0.05f;
ShapeAndPos.x = (BGShapeAndPos.x + (BGShapeAndPos.w * PercentageAlong)) - (ShapeAndPos.w/2);
ShapeAndPos.h = BGShapeAndPos.h * 2.5f;
ShapeAndPos.y = BGShapeAndPos.y - ((ShapeAndPos.h - BGShapeAndPos.h)/2);
//Check if the mouse is inside the object
CheckInside(MousePos);
//if the object has been grabbed
if (bGrabbed)
{
//then we are inside
IsInside = true;
//calculate slider ranges
float Left = (BGShapeAndPos.x + (BGShapeAndPos.w * 0)) - (ShapeAndPos.w / 2);
float Right = (BGShapeAndPos.x + (BGShapeAndPos.w * 1)) - (ShapeAndPos.w / 2);
//Update the object to match the mouse pos
ShapeAndPos.x = (MousePos.X) - (ShapeAndPos.w / 2);
//Clamp within ranges
ShapeAndPos.x = FMath::Clamp<float>(ShapeAndPos.x, Left, Right);
//work out the new percentage to return
PercentageAlong = ((ShapeAndPos.x - BGShapeAndPos.x) + (ShapeAndPos.w / 2)) / BGShapeAndPos.w;
//Calculate the amount to return
Amount = MaxAmount * PercentageAlong;
//Clamp again just to be sure
Amount = FMath::Clamp<float>(Amount, MinAmount, MaxAmount);
}//if
//If the BG material reference isn't null, and the passed HUD isn't null
if (HUDRef != NULL)
{
if (MIObj != NULL)
{
//Draw the material as assigned
HUDRef->DrawMaterialSimple(MIObj, ShapeAndPos.x, ShapeAndPos.y, ShapeAndPos.w, ShapeAndPos.h, 1, false);
}//if
}//if
return Amount;
}//DrawHorizontalSlider
float UHUDObjects::DrawVerticalSlider(AHUD* HUDRef, float Amount, float MinAmount, float MaxAmount, FVector2D MousePos, float x, float y, float w, float h, float Scale)
{
//Set vars
BGShapeAndPos.x = x;
BGShapeAndPos.y = y;
BGShapeAndPos.w = w;
BGShapeAndPos.h = h;
ScaleAmount = Scale;
//Work out how much to extend the slider to make it fit correctly
float BGHeightAdd = BGShapeAndPos.h * 0.08f;
//If the BG material reference isn't null, and the passed HUD isn't null
if (HUDRef != NULL)
{
if (BGMIObj != NULL)
{
//Draw the material as assigned
HUDRef->DrawMaterialSimple(BGMIObj, BGShapeAndPos.x, BGShapeAndPos.y - BGHeightAdd, BGShapeAndPos.w, BGShapeAndPos.h + (BGHeightAdd * 2), 1, false);
}//if
}//if
//Get a percentage between 0-1
float PercentageAlong = Amount / (MaxAmount - MinAmount);
//Inverting
PercentageAlong = 1 - PercentageAlong;
//Work out the size/position of the slider, based off of the total size
ShapeAndPos.h = BGShapeAndPos.h*0.05f;
ShapeAndPos.y = (BGShapeAndPos.y + (BGShapeAndPos.h * PercentageAlong)) - (ShapeAndPos.h / 2);
ShapeAndPos.w = BGShapeAndPos.w * 2.5f;
ShapeAndPos.x = BGShapeAndPos.x - ((ShapeAndPos.w - BGShapeAndPos.w) / 2);
//Check if the mouse is inside the object
CheckInside(MousePos);
//if the object has been grabbed
if (bGrabbed)
{
//then we are inside the button
IsInside = true;
//Work out the ranges the slider can meet
float Top = (BGShapeAndPos.y + (BGShapeAndPos.h * 0)) - (ShapeAndPos.h / 2);
float Bottom = (BGShapeAndPos.y + (BGShapeAndPos.h * 1)) - (ShapeAndPos.h / 2);
//Update the object to match the mouse pos
ShapeAndPos.y = (MousePos.Y) - (ShapeAndPos.h / 2);
//Clamp within ranges
ShapeAndPos.y = FMath::Clamp<float>(ShapeAndPos.y, Top, Bottom);
//Work out the percentage to return
PercentageAlong = ((ShapeAndPos.y - BGShapeAndPos.y) + (ShapeAndPos.h / 2)) / BGShapeAndPos.h;
//Inverting
PercentageAlong = 1 - PercentageAlong;
//Calculate the amount
Amount = MaxAmount * PercentageAlong;
//Clamp it just to be sure
Amount = FMath::Clamp<float>(Amount, MinAmount, MaxAmount);
}//if
//If the BG material reference isn't null, and the passed HUD isn't null
if (HUDRef != NULL)
{
if (MIObj != NULL)
{
//Draw the material as assigned
HUDRef->DrawMaterialSimple(MIObj, ShapeAndPos.x, ShapeAndPos.y, ShapeAndPos.w, ShapeAndPos.h, 1, false);
}//if
}//if
return Amount;
}//DrawVerticalSlider
void UHUDObjects::DrawTexture(AHUD* HUDRef, float x, float y, float w, float h, FColor pColour)
{
//if the hud exists
if (HUDRef != NULL)
{
//if the texture exists
if (Texture != NULL)
{
//Draw the texture
HUDRef->DrawTexture(Texture, x, y,
w - (w * CropX),
h - (h * CropY),
0 + CropX,
0 + CropY,
(1 - CropU) + CropX,
(1 - CropV) + CropY,
pColour);
}//if
}//if
}
void UHUDObjects::CropObjectUV(FVector2D UVCrop)
{
//Pass in vars within clamped ranges
CropU = FMath::Clamp<float>(UVCrop.X, 0, 1);
CropV = FMath::Clamp<float>(UVCrop.Y, 0, 1);
}//CropObjectUV
void UHUDObjects::CropObjectXY(FVector2D XYCrop)
{
//Pass in vars within clamped ranges
CropX = FMath::Clamp<float>(XYCrop.X, 0, 1);
CropY = FMath::Clamp<float>(XYCrop.Y, 0, 1);
}//CropObjectXY
GUI.h
251 Lines
#pragma once
#include "GameFramework/HUD.h"
#include "HUDObjects.h"
#include "GUI.generated.h"
USTRUCT()
struct FButtonMaterial
{
GENERATED_USTRUCT_BODY()
//The material to be used for this HUD object
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Buttons)
UMaterialInterface* Material;
//Name of the material var for toggling Highlighting
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Buttons)
FString HighLightVarName;
//Name of the material var for toggling Selection
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
FString ClickVarName;
FButtonMaterial()
{
//Defaults
HighLightVarName = "HighLight";
ClickVarName = "Click";
}
};
USTRUCT()
struct FAnimationStruct
{
GENERATED_USTRUCT_BODY()
//The material to be used for this HUD object
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
UMaterialInterface* Material;
//Name of the material var for toggling Highlighting
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
FString HighLightVarName;
//Name of the material var for toggling Selection
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
FString ClickVarName;
//Animation Rows and Columns
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
FVector2D AnimColRows;
//Total Number of tiles in the animation
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
float TotalAnimTiles;
//Time between each frame
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
float FrameDelaySeconds;
FAnimationStruct()
{
//Defaults
TotalAnimTiles = 0;
FrameDelaySeconds = 0.5f;
HighLightVarName = "";
ClickVarName = "";
}
};
UCLASS()
class AGUI : public AHUD
{
GENERATED_UCLASS_BODY()
// Infiltrace
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Text)
TArray<UFont*> Fonts;
//Font scale
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Text)
float DefaultFontScale;
//Button Materials
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Buttons)
TArray<FButtonMaterial> ButtonMaterials;
//Image Textures
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Textures)
TArray<UTexture2D*> ImageTextures;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Materials)
TArray<UMaterialInterface*> Materials;
//Animated Materials
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
TArray<FAnimationStruct> AnimationMaterials;
// Draw Hud?
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Options)
bool NoHUD;
public:
//Reference to the Player Controller
UPROPERTY()
APlayerController* ThePC;
protected:
//Screen Sizes
UPROPERTY()
float SizeX;
UPROPERTY()
float SizeY;
/*
* GUI Object that creates a label with simple, centered text
* @param Object (out) - The object to be instantiated and/or updated
* @param pHUDRef - The hud pointer to be passed : this
* @param pText - The text to be displayed
* @param FontIndex - The font to be used from this HUD's FONT array
* @param TextColour - The colour of the font to be displayed
* @param x - The start horizontal position of the object in pixels
* @param y - The start vertical position of the object in pixels
* @param w - The width of the object in pixels
* @param h - The height of the object in pixels
* @param pScale - Standard AHUD scaling
*/
void Label(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, FString pText, int FontIndex, FLinearColor TextColour, float x, float y, float w, float h, float pScale = 1);
/*
* GUI Object that creates a texture at a specified location, with a given size and colour
* @param Object (out) - The object to be instantiated and/or updated
* @param pHUDRef - The hud pointer to be passed : this
* @param TextureIndex - The texture to be used from this HUD's TEXTURE array
* @param x - The start horizontal position of the object in pixels
* @param y - The start vertical position of the object in pixels
* @param w - The width of the object in pixels
* @param h - The height of the object in pixels
* @param pColour - The colour adjustment that should be applied to the texture
*/
void Texture(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, int TextureIndex, float x, float y, float w, float h, FColor pColour = FColor::White);
/*
* GUI Object that creates a basic material, with a given size and position
* @param Object (out) - The object to be instantiated and/or updated
* @param pHUDRef - The hud pointer to be passed : this
* @param MatIndex - The material to be used from this HUD's MATERIAL array
* @param pText - The text to be displayed
* @param FontIndex - The font to be used from this HUD's FONT array
* @param TextColour - The colour of the font to be displayed
* @param x - The start horizontal position of the object in pixels
* @param y - The start vertical position of the object in pixels
* @param w - The width of the object in pixels
* @param h - The height of the object in pixels
* @param pScale - Standard AHUD scaling
*/
void Material(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, int MatIndex, FString pText, int FontIndex, FLinearColor TextColour, float x, float y, float w, float h, float pScale = 1);
/*
* GUI Object that creates an Animated Sprite Sheet Material, with a given size and position
* @param Object (out) - The object to be instantiated and/or updated
* @param pHUDRef - The hud pointer to be passed : this
* @param AnimIndex - The animated material to be used from this HUD's ANIMATEDMATERIAL array
* @param x - The start horizontal position of the object in pixels
* @param y - The start vertical position of the object in pixels
* @param w - The width of the object in pixels
* @param h - The height of the object in pixels
* @param pScale - Standard AHUD scaling
*/
void AnimatedMaterial(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, int AnimIndex, float x, float y, float w, float h, float pScale = 1);
/*
* GUI Object that acts as a button, with 3 states: Normal, Highlighted and Clicked. Returns a bool if clicked
* @param Object (out) - The object to be instantiated and/or updated
* @param pHUDRef - The hud pointer to be passed : this
* @param ButtonIndex - The button material to be used from this HUD's BUTTONMATERIAL array
* @param pText - The text to be displayed
* @param FontIndex - The font to be used from this HUD's FONT array
* @param TextColour - The colour of the font to be displayed
* @param pMousePos - The position of the mouse in screen space
* @param x - The start horizontal position of the object in pixels
* @param y - The start vertical position of the object in pixels
* @param w - The width of the object in pixels
* @param h - The height of the object in pixels
* @param pScale - Standard AHUD scaling
*/
bool Button(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, int ButtonIndex, FString pText, int FontIndex, FLinearColor TextColour, FVector2D pMousePos, float x, float y, float w, float h, float pScale = 1);
/*
* GUI Object that acts as a button, with 3 animated sprite sheet states: Normal, Highlighted and Clicked. Returns a bool if clicked
* @param Object (out) - The object to be instantiated and/or updated
* @param pHUDRef - The hud pointer to be passed : this
* @param AnimButtonIndex - The button material to be used from this HUD's ANIMATEDMATERIAL array
* @param pText - The text to be displayed
* @param FontIndex - The font to be used from this HUD's FONT array
* @param TextColour - The colour of the font to be displayed
* @param pMousePos - The position of the mouse in screen space
* @param x - The start horizontal position of the object in pixels
* @param y - The start vertical position of the object in pixels
* @param w - The width of the object in pixels
* @param h - The height of the object in pixels
* @param pScale - Standard AHUD scaling
*/
bool AnimatedButton(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, int AnimButtonIndex, FString pText, int FontIndex, FLinearColor TextColour, FVector2D pMousePos, float x, float y, float w, float h, float pScale = 1);
/*
* GUI Object that returns the updated value of the slider
* @param Object (out) - The object to be instantiated and/or updated
* @param pHUDRef - The hud pointer to be passed : this
* @param SliderButtonIndex - The button material to be used from this HUD's BUTTONMATERIAL array
* @param SliderBackgroundMaterialIndex - The button material to be used from this HUD's MATERIAL array
* @param pMousePos - The position of the mouse in screen space
* @param x - The start horizontal position of the object in pixels
* @param y - The start vertical position of the object in pixels
* @param w - The width of the object in pixels
* @param h - The height of the object in pixels
* @param Amount - The amount to be passed in on this update pass
* @param MinAmount - The minimum amount to be used in this slider
* @param MaxAmount - The maximum amount to be used in this slider
*/
float HorizontalSlider(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, int SliderButtonIndex, int SliderBackgroundMaterialIndex, FVector2D pMousePos, float x, float y, float w, float h, float Amount = 0, float MinAmount = 0, float MaxAmount = 1);
/*
* GUI Object that returns the updated value of the slider
* @param Object (out) - The object to be instantiated and/or updated
* @param pHUDRef - The hud pointer to be passed : this
* @param SliderButtonIndex - The button material to be used from this HUD's BUTTONMATERIAL array
* @param SliderBackgroundMaterialIndex - The button material to be used from this HUD's MATERIAL array
* @param pMousePos - The position of the mouse in screen space
* @param x - The start horizontal position of the object in pixels
* @param y - The start vertical position of the object in pixels
* @param w - The width of the object in pixels
* @param h - The height of the object in pixels
* @param Amount - The amount to be passed in on this update pass
* @param MinAmount - The minimum amount to be used in this slider
* @param MaxAmount - The maximum amount to be used in this slider
*/
float VerticalSlider(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, int SliderButtonIndex, int SliderBackgroundMaterialIndex, FVector2D pMousePos, float x, float y, float w, float h, float Amount = 0, float MinAmount = 0, float MaxAmount = 1);
//Scaling
float CenterHorizontal(float Width);
float CenterVertical(float Height);
float ScaleWidth(float Width);
float ScaleHeight(float Height);
/** after all game elements are created */
virtual void PostInitializeComponents() OVERRIDE;
virtual void DrawHUD() OVERRIDE;
};
GUI.cpp
346 Lines
#include "YourGame.h"
#include "GUI.h"
//Constructor
AGUI::AGUI(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
{
//Draw HUD?
NoHUD = false;
//Scale
DefaultFontScale = 0.7;
}//Constructor
//SCALING
float AGUI::ScaleWidth(float Width)
{
return (Width / 1920)*SizeX;
}///Scale Width
float AGUI::CenterHorizontal(float Width)
{
return (SizeX / 2) - (ScaleWidth(Width) / 2);
}//CenterHorizontal
float AGUI::ScaleHeight(float Height)
{
return (Height / 1920)*SizeY;
}//ScaleHeight
float AGUI::CenterVertical(float Height)
{
return (SizeY / 2) - (ScaleHeight(Height) / 2);
}//CenterVertical
//CORE
void AGUI::PostInitializeComponents()
{
Super::PostInitializeComponents();
//Grab the PC
ThePC = GetOwningPlayerController();
}//PostInitializeComponents
void AGUI::DrawHUD()
{
//If the PC is NULL
if (!ThePC)
{
//Try to get the PC
ThePC = GetOwningPlayerController();
//If there still isn't a PC, then return
if (!ThePC) return;
}//if
//Check that the PC's input exists, otherwise, return
if (!ThePC->PlayerInput) return;
//Draw HUD?
if (NoHUD) return;
//Super
Super::DrawHUD();
//No Canvas?
if (!Canvas) return;
//Assign the canvas sizes to the global vars for use outside of DrawHUD
SizeX = Canvas->SizeX;
SizeY = Canvas->SizeY;
}//DrawHUD
//GUI WIDGETS
void AGUI::Label(UHUDObjects* & Object, AHUD* pHUDRef, FString pText, int FontIndex, FLinearColor TextColour, float x, float y, float w, float h, float pScale)
{
//Instantiate new object and assign reference to the pointer
if (Object == NULL)
{
//If the pointer has an object
if (Fonts.IsValidIndex(FontIndex) && Fonts[FontIndex] != nullptr)
{
Object = NewObject<UHUDObjects>(this);
if (Object != NULL)
{
//Set up the HUD Object
Object->Init(pText, Fonts[FontIndex]);
}//if
}//if
}//if
else
{
//Update the object
Object->Update(pHUDRef, FVector2D(0, 0), x, y, w, h, pScale, TextColour);
}//else
}//Label
void AGUI::Texture(/* Out */ UHUDObjects* & Object, AHUD* pHUDRef, int TextureIndex, float x, float y, float w, float h, FColor pColour)
{
if (Object == NULL)
{
//If the pointer has an object
if (ImageTextures.IsValidIndex(TextureIndex) && ImageTextures[TextureIndex] != nullptr)
{
Object = NewObject<UHUDObjects>(this);
if (Object != NULL)
{
//Set up the HUD Object
Object->Init(ImageTextures[TextureIndex]);
}//if
}//if
}//if
else
{
//Update the object
Object->DrawTexture(pHUDRef, x, y, w, h, FColor::White);
}//else
}//Texture
void AGUI::Material(UHUDObjects* & Object, AHUD* pHUDRef, int MatIndex, FString pText, int FontIndex, FLinearColor TextColour, float x, float y, float w, float h, float pScale)
{
if (Object == NULL)
{
//If the pointer has an object
if (ButtonMaterials.IsValidIndex(MatIndex) && ButtonMaterials[MatIndex].Material != nullptr && Fonts.IsValidIndex(FontIndex) && Fonts[FontIndex] != nullptr)
{
Object = NewObject<UHUDObjects>(this);
if (Object != NULL)
{
//Set up the HUD Object
Object->Init(false, Materials[MatIndex], "", "", pText, Fonts[FontIndex]);
}//if
}//if
}//if
else
{
//Update object
Object->Update(pHUDRef, FVector2D(0, 0), x, y, w, h, pScale, TextColour);
}//else
}//Material
void AGUI::AnimatedMaterial(UHUDObjects* & Object, AHUD* pHUDRef, int AnimIndex, float x, float y, float w, float h, float pScale)
{
//Instantiate new object and assign reference to the pointer
if (Object == NULL)
{
//If the pointer has an object
if (AnimationMaterials.IsValidIndex(AnimIndex) && AnimationMaterials[AnimIndex].Material != nullptr)
{
Object = NewObject<UHUDObjects>(this);
if (Object != NULL)
{
//Set up the HUD Object
Object->Init(false, AnimationMaterials[AnimIndex].Material, AnimationMaterials[AnimIndex].HighLightVarName, AnimationMaterials[AnimIndex].ClickVarName, AnimationMaterials[AnimIndex].AnimColRows, AnimationMaterials[AnimIndex].TotalAnimTiles, AnimationMaterials[AnimIndex].FrameDelaySeconds);
}
}//if
}//if
else
{
//Update the object
Object->Update(pHUDRef, FVector2D(0,0), x, y, w, h, pScale);
}//else
}//Animated Material
bool AGUI::Button(UHUDObjects* & Object, AHUD* pHUDRef, int ButtonIndex, FString pText, int FontIndex, FLinearColor TextColour, FVector2D pMousePos, float x, float y, float w, float h, float pScale)
{
//If the object doesn't exit
if (Object == NULL)
{
//If the pointer has an object
if (ButtonMaterials.IsValidIndex(ButtonIndex) && ButtonMaterials[ButtonIndex].Material != nullptr && Fonts.IsValidIndex(FontIndex) && Fonts[FontIndex] != nullptr)
{
//create a new version of the object
Object = NewObject<UHUDObjects>(this);
if (Object != NULL)
{
//Set up the HUD Object
Object->Init(true, ButtonMaterials[ButtonIndex].Material, ButtonMaterials[ButtonIndex].HighLightVarName, ButtonMaterials[ButtonIndex].ClickVarName, pText, Fonts[FontIndex]);
}//if
}//if
return false;
}//if
else
{
//Update the object
Object->Update(pHUDRef, pMousePos, x, y, w, h, pScale, TextColour);
//If the left mouse button is down
if (ThePC->IsInputKeyDown(EKeys::LeftMouseButton))
{
//if the object is hovered and the button was just pressed
if (Object->Hovered() && ThePC->WasInputKeyJustPressed(EKeys::LeftMouseButton))
{
//we have grabbed the object
Object->bGrabbed = true;
}//if
}//if
else
{
//if the object has been grabbed
if (Object->bGrabbed)
{
//set it to false
Object->bGrabbed = false;
return Object->Hovered();
}//if
return false;
}//else
return false;
}//else
}//button
bool AGUI::AnimatedButton(UHUDObjects* & Object, AHUD* pHUDRef, int AnimButtonIndex, FString pText, int FontIndex, FLinearColor TextColour, FVector2D pMousePos, float x, float y, float w, float h, float pScale)
{
//Instantiate new object and assign reference to the pointer
if (Object == NULL)
{
//If the pointer has an object
if (AnimationMaterials.IsValidIndex(AnimButtonIndex) && AnimationMaterials[AnimButtonIndex].Material != nullptr && Fonts.IsValidIndex(FontIndex) && Fonts[FontIndex] != nullptr)
{
//create a new object
Object = NewObject<UHUDObjects>(this);
if (Object != NULL)
{
//Set up the HUD Object
Object->Init(true, AnimationMaterials[AnimButtonIndex].Material, AnimationMaterials[AnimButtonIndex].HighLightVarName, AnimationMaterials[AnimButtonIndex].ClickVarName, pText, Fonts[FontIndex], AnimationMaterials[AnimButtonIndex].AnimColRows, AnimationMaterials[AnimButtonIndex].TotalAnimTiles, AnimationMaterials[AnimButtonIndex].FrameDelaySeconds);
}//if
}//if
return false;
}//if
else
{
//update object
Object->Update(pHUDRef, pMousePos, x, y, w, h, pScale, TextColour);
//if the left mouse button is down
if (ThePC->IsInputKeyDown(EKeys::LeftMouseButton))
{
//if the mouse is over the object and the button was pressed during this frame
if (Object->Hovered() && ThePC->WasInputKeyJustPressed(EKeys::LeftMouseButton))
{
//we have grabbed the object
Object->bGrabbed = true;
}//if
}//if
else
{
//if the object has been grabbed
if (Object->bGrabbed)
{
//set it to false
Object->bGrabbed = false;
return Object->Hovered();
}//if
return false;
}//else
return false;
}//else
}//AnimatedButton
float AGUI::HorizontalSlider(UHUDObjects* & Object, AHUD* pHUDRef, int SliderButtonIndex, int SliderBackgroundMaterialIndex, FVector2D pMousePos, float x, float y, float w, float h, float Amount, float MinAmount, float MaxAmount)
{
if (Object == NULL)
{
//If the pointer has an object
if (ButtonMaterials.IsValidIndex(SliderButtonIndex) && ButtonMaterials[SliderButtonIndex].Material != nullptr && Materials.IsValidIndex(SliderBackgroundMaterialIndex) && Materials[SliderBackgroundMaterialIndex] != nullptr)
{
Object = NewObject<UHUDObjects>(this);
if (Object != NULL)
{
//Set up the HUD Object
Object->Init(true, ButtonMaterials[SliderButtonIndex].Material, ButtonMaterials[SliderButtonIndex].HighLightVarName, ButtonMaterials[SliderButtonIndex].ClickVarName, Materials[SliderBackgroundMaterialIndex]);
}//if
}//if
return Amount;
}//if
else
{
if (ThePC->IsInputKeyDown(EKeys::LeftMouseButton))
{
if ((Object->Hovered() || Object->CheckInsideSliderBG(pMousePos)) && ThePC->WasInputKeyJustPressed(EKeys::LeftMouseButton))
{
Object->bGrabbed = true;
}//if
}//if
else
{
if (Object->bGrabbed)
{
Object->bGrabbed = false;
}//if
}//else
//Clamp the range just to be sure
Amount = FMath::Clamp<float>(Amount, MinAmount, MaxAmount);
//Draw slider button
return Object->DrawHorizontalSlider(pHUDRef, Amount, MinAmount, MaxAmount, pMousePos, x, y, w, h, 1);
}//else
return Amount;
}//HorizontalSlider
float AGUI::VerticalSlider(UHUDObjects* & Object, AHUD* pHUDRef, int SliderButtonIndex, int SliderBackgroundMaterialIndex, FVector2D pMousePos, float x, float y, float w, float h, float Amount, float MinAmount, float MaxAmount)
{
if (Object == NULL)
{
//If the pointer has an object
if (ButtonMaterials.IsValidIndex(SliderButtonIndex) && ButtonMaterials[SliderButtonIndex].Material != nullptr && Materials.IsValidIndex(SliderBackgroundMaterialIndex) && Materials[SliderBackgroundMaterialIndex] != nullptr)
{
Object = NewObject<UHUDObjects>(this);
if (Object != NULL)
{
//Set up the HUD Object
Object->Init(true, ButtonMaterials[SliderButtonIndex].Material, ButtonMaterials[SliderButtonIndex].HighLightVarName, ButtonMaterials[SliderButtonIndex].ClickVarName, Materials[SliderBackgroundMaterialIndex]);
}//if
}//if
return Amount;
}//if
else
{
if (ThePC->IsInputKeyDown(EKeys::LeftMouseButton))
{
if ((Object->Hovered() || Object->CheckInsideSliderBG(pMousePos)) && ThePC->WasInputKeyJustPressed(EKeys::LeftMouseButton))
{
Object->bGrabbed = true;
}//if
}//if
else
{
if (Object->bGrabbed)
{
Object->bGrabbed = false;
}//if
}//else
//Clamp the range just to be sure
Amount = FMath::Clamp<float>(Amount, MinAmount, MaxAmount);
//Draw slider button
return Object->DrawVerticalSlider(pHUDRef, Amount, MinAmount, MaxAmount, pMousePos, x, y, w, h, 1);
}//else
return Amount;
}//VerticalSlider
YourHUD.h
42 Lines
#pragma once
#include "GUI.h"
#include "YourHUD.generated.h"
UCLASS()
class AYourHUD : public AGUI
{
GENERATED_UCLASS_BODY()
public:
//Objects we will be using to demonstrate each type of object
UPROPERTY()
UHUDObjects* TestLabel;
UPROPERTY()
UHUDObjects* TestTexture;
UPROPERTY()
UHUDObjects* TestMaterial;
UPROPERTY()
UHUDObjects* TestAnimMaterial;
UPROPERTY()
UHUDObjects* TestButton;
UPROPERTY()
UHUDObjects* TestAnimButton;
UPROPERTY()
UHUDObjects* TestHorizontalSlider;
UPROPERTY()
UHUDObjects* TestVerticalSlider;
//Variables to hold for the sliders
float horizontalSlideValue;
float verticalSlideValue;
//Variable to hold mouse position
UPROPERTY()
FVector2D MousePos;
protected:
//Draw HUD
virtual void DrawHUD() OVERRIDE;
};
YourHUD.cpp
72 Lines
#include "YourGame.h"
#include "YourHUD.h"
//Constructor
AYourHUD::AYourHUD(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
{
//Default the mouse positions
MousePos.X = 0;
MousePos.Y = 0;
//Default the slider values
horizontalSlideValue = 0;
verticalSlideValue = 0;
}//Constructor
void AYourHUD::DrawHUD()
{
//If the PC is NULL
if (!ThePC)
{
//Try to get the PC
ThePC = GetOwningPlayerController();
//If there still isn't a PC, then return
if (!ThePC) return;
}//if
//Check that the PC's input exists, otherwise, return
if (!ThePC->PlayerInput) return;
//Draw HUD?
if (NoHUD) return;
//Super
Super::DrawHUD();
//No Canvas?
if (!Canvas) return;
//Grab the mouse position
ThePC->GetMousePosition(MousePos.X, MousePos.Y);
//This works by passing the object, this hud, the text, the index of the font array you want to use, the mouse position, then rectangle positioning, using scaling functions, and then the font size, scaled to the screen.
Label(TestLabel, this, "This is a label!", 0, FLinearColor::White, CenterHorizontal(300), ScaleHeight(120), ScaleWidth(300), ScaleHeight(120), ScaleWidth(0.75f));
//This works by passing the object, this hud, the index of the texture array you want to use, then rectangle positioning, and finally a tint colour
Texture(TestTexture, this, 0, CenterHorizontal(300), ScaleHeight(240), ScaleWidth(300), ScaleHeight(120), FColor::White);
//This works by passing the object, this hud, the index of the material array you want to use, the text, the index of the font array you want to use, rectangle positioning, and font/material scaling
Material(TestMaterial, this, 0, "This is a material!", 0, FLinearColor::White, CenterHorizontal(300), ScaleHeight(360), ScaleWidth(300), ScaleHeight(120), ScaleWidth(0.75f));
//This works by passing the object, this hud, the index of the animated material array you want to use, rectangle positions, and font/material scaling
AnimatedMaterial(TestAnimMaterial, this, 0, CenterHorizontal(300), ScaleHeight(480), ScaleWidth(300), ScaleHeight(120), ScaleWidth(0.75f));
//This works by passing the object, this hud, then index of the button material array you want to use, the text, the index of the font, the font colour, the mouse position, rectangle positioning and font/material scaling
if(Button(TestButton, this, 0, "This is a button!", 0, FLinearColor::White, MousePos, CenterHorizontal(300), ScaleHeight(600), ScaleWidth(300), ScaleHeight(120), ScaleWidth(0.75f)))
{
//Stuff goes here for when button is clicked
}//if
//This works by passing the object, this hud, then index of the animated button material array you want to use, the text, the index of the font, the font colour, the mouse position, rectangle positioning and font/material scaling
if(AnimatedButton(TestAnimButton, this, 0, "This is an animated button!", 0, FLinearColor::White, MousePos, CenterHorizontal(300), ScaleHeight(720), ScaleWidth(300), ScaleHeight(120), ScaleWidth(0.75f)))
{
//Stuff goes here for when button is clicked
}//if
//This works by passing the object, this hud, the index of the button for the slider, the index for the material for the background, rectangle positioning, the current value, the min value and the max value.
horizontalSlideValue = HorizontalSlider(TestHorizontalSlider, this, 0, 0, MousePos, CenterHorizontal(300), ScaleHeight(840), ScaleWidth(300), ScaleHeight(7.5f), horizontalSlideValue, 0, 1);
//This works by passing the object, this hud, the index of the button for the slider, the index for the material for the background, rectangle positioning, the current value, the min value and the max value.
verticalSlideValue = HorizontalSlider(TestVerticalSlider, this, 0, 0, MousePos, CenterHorizontal(400), CenterVertical(300), ScaleWidth(7.5f), ScaleHeight(300), verticalSlideValue, 0, 1);
}//DrawHUD
BluePrint/Editor End
Once you have compild your new project, make a new Class BluePrint of "YourHUD" and set the new BP to be your HUD System. Open the BluePrint and go into the defaults.
Text Section
Drop down the Text section, add an element to the Fonts array, and add in the font you created earlier. Any time the script asks for a 'Font Index', it's referring to the element number of this array. (On the left)
Buttons Section
Drop down the Button section, add an element to the Button Materials array, and add in the button material you created earlier. Set the Highlight and Click names to be the respective parameters in that material. Any time the script asks for a 'Button Index' or 'Slider Button Index', it's referring to the element number of this array. (On the left)
Textures Section
Drop down the Textures section, add an element to the Image Textures array, and add in the texture you want. Any time the script asks for a 'Texture Index', it's referring to the element number of this array. (On the left)
Materials Section
Drop down the Materials section, add an element to the Materials array, and add in the simple material you made earlier. Any time the script asks for a 'Material Index' or 'Slider Background Material Index', it's referring to the element number of this array. (On the left)
Animations Section
Drop down the Animations section, add an element to the Animation Materials array, and add in the simple or button material you created earlier. NOTE: This expects the textures of the material to be in a sprite sheet layout. If its a Button, then set the Highlight and Click names to be the respective parameters in that material. Any time the script asks for a 'Anim Button Index' or 'Anim Index', it's referring to the element number of this array. (On the left)
The 'Anim Col Rows' is how many sprites across the texture is, then how many down. Total anim tiles is how many tiles there are altogether, in case it doesn't go all the way to the end. The Frame Delay Seconds is how much time you want there to be between frame updates.
Conclusion
You can take this code and make whatever kind of HUD system you want. I never demonstrated it, but there are functions in the GUI class that can crop animated materials, so you can have an animated health bar thats cropped from the left, making it look like it's decreasing without cutting off at the right. 'CropXY(FVector2D)' and 'CropUV(FVector2D)'
You can also set up your own mouse system that doesn't use 'ThePC->GetMousePosition()' and implement a cool feature like gamepad control, etc.
-Peace