Natural Selection 2

Natural Selection 2

Not enough ratings
DIY GUI
By Huze
Learn how to make GUIs in Spark. This guide is a work in progress. I will continue to fill it out as time goes on.
   
Award
Favorite
Favorited
Unfavorite
Defining a GUIScript
GUIDIY.lua
class 'GUIDIY' (GUIScript) GUIDIY:Initialize() end GUIDIY:Uninitialize() end GUIDIY:Update(deltaTime) end GUIDIY:OnResolutionChanged(oldX, oldY, newX, newY) end GUIDIY:SendKeyEvent(key, down) end end

Initialize()
A constructor, Initialize is called when the GUIScript is created. This is a good place to initialize variables.

Uninitialize()
A destructor, Uninitialize is called when the GUIScript is destroyed. This is the place to destroy all your things so they don't leak. I'll cover how to destroy stuff in the next section.

Update(deltaTime)
Called every tick by the GUIManager.

OnResolutionChanged(oldX, oldY, newX, newY)
Called when the client resizes the screen. This is a when you should resize or rescale your GUI to better fit their new screen size.

SendKeyEvent(key, down)
Called on key events. Return true if you'd like to "consume" the event.
key can be compared to any "InputKey" value, down corresponds to whether the key is pressed or released.
Creating and Destroying a GUI
Creating a GUIScript
Create your GUI.
GetGUIManager():CreateGUIScriptSingle("GUIDIY")
GetGUIManager():DestroyGUIScriptSingle("GUIDIY")

Create an instance of your GUI. Create and destroy as many as you want!
local script = GetGUIManager():CreateGUIScript("GUIDIY")
GetGUIManager():DestroyGUIScript(script)

Creating a GUIItem
item = GUIManager:CreateGraphicItem()
text = GUIManager:CreateTextItem()

GUI.DestroyItem(item)

All GUI items must be destroyed using DestroyItem or they will "leak". If you lose your reference to the GUI item before destroying it you will end up with phantom GUI items on the screen. These can only be removed by rejoining a server. DestroyItem will also destroy any children of the item you're destroying.
Position, Size, and Scale
SetPosition(Vector(x,y,0))
Set the position (in pixels) of the item. Positioning is based on the top left corner. This works based on standard computer positioning rules. Increasing X goes Right across the screen. Increasing Y goes Down across the screen. Use of negative numbers is allowed. Use Client.GetScreenHeight() and Client.GetScreenWidth() to get the size of the current screen.

SetSize(Vector(w,h,0))
Set the size (in pixels) of the item. Negative numbers can be used to flip the item across an axis (origin at top left corner).

SetScale(Vector(i,j,0))
Set the scale of the item.

Anchor
item:SetAnchor(xAnchor, yAnchor)
Set the Anchor of a GUI item. The anchor determines where the GUI will base its positioning from. The image below demonstrates where you can set your anchors.

X Anchors
GUIItem.Left
GUIItem.Middle
GUIItem.Right

Y Anchors
GUIItem.Top
GUIItem.Center
GUIItem.Bottom

Color and Texture
SetColor(Color(r,g,b,a))
Set the color of the GUI. If a texture is set the color will be multiplied into the texture. Use white to keep your texture the default color.

SetTexture("ui/texture.dds")
Set the texture to the given texture. Can be assigned to dds, psd, or png(?) images.

SetTexturePixelCoordinates(x,y,w,h)
Set the texture's sample coordinates. Example below, the red dotted box represents the coordinates sampled on the texture. Negative values can be used to mirror the image.
Use "unpack({x,w,w,h})" to pass in a single table, or pass in each parameter seperately.

Text
Text works similar to other GUI elements, but there are some differences

GUIManager:CreateTextItem()
Creates a new Text Item

SetFontName("fonts/Font_size.fnt")
Set the font. Look in your "natural selection 2/core/fonts" directory to see existing NS2 fonts. // TODO make a tutorial on creating fonts

SetText("String")
Set the text to be displayed

SetScale(Vector(xScale, yScale, 0))
Set the scale. There is no "SetSize" for text items, you must use SetScale to change the size of your text items.

SetTextAlignmentX(Alignment)
Set the x Alignment.

SetTextAlignmentY(Alignment)
Set the y Alignment

Alignments will change the positioning of the item from the top left (min, min) corner to whatever values are set.
Alignments
GUIItem.Align_Min
GUIItem.Align_Center
GUIItem.Align_Max

Lines
Lines can only be 1 px thick right now.
Most of the regular GUI functions will work: Anchor, Position, Color, Visible, Layer, Parent, etc

Line Specific functions:
lineItem = GUIManager:CreateLinesItem()
Create a new Lines Graphic Item

AddLine(VectorPosition1, VectorPosition2, Color)
Draws a line from position1 to position2 with color

ClearLines()
Clears all the lines from a Lines Item
Other Commands
AddChild(GUIItem)
Adds a child to the gui item. A child will use its parent's position as its origin instead of (0,0). Children/Parents are covered elsewhere in the guide

SetRotation(radian float)
Set rotation, //TODO I think this rotates around the top left corner.

SetLayer(int)
Sets the layer of the item. 0 is the lowest layer. Check GUIManager.lua to see some layer constants.

SetIsVisible(boolean)
Sets the item and all children invisible

GetScreenPosition(Client.GetScreenWidth(), Client.GetScreenHeight())
Gets the absolute screen position of the item. If the item is a child, GetPosition() will return its relative position, not its absolute position.

SetInheritsParentAlpha(true)
Item will inherit its parent's alpha.
Examples

Drawing Overhead camer projection lines from GUIMinimap.lua
self.cameraLines = GUIManager:CreateLinesItem() self.cameraLines:SetAnchor(GUIItem.Center, GUIItem.Middle) self.cameraLines:SetLayer(kPlayerIconLayer) self.minimap:AddChild(self.cameraLines) ... local topLeftPoint, topRightPoint, bottomLeftPoint, bottomRightPoint = OverheadUI_ViewFarPlanePoints() topLeftPoint = Vector(PlotToMap(self, topLeftPoint.x, topLeftPoint.z)) topRightPoint = Vector(PlotToMap(self, topRightPoint.x, topRightPoint.z)) bottomLeftPoint = Vector(PlotToMap(self, bottomLeftPoint.x, bottomLeftPoint.z)) bottomRightPoint = Vector(PlotToMap(self, bottomRightPoint.x, bottomRightPoint.z)) self.cameraLines:ClearLines() local lineColor = Color(1, 1, 1, 1) self.cameraLines:AddLine(topLeftPoint, topRightPoint, lineColor) self.cameraLines:AddLine(topRightPoint, bottomRightPoint, lineColor) self.cameraLines:AddLine(bottomRightPoint, bottomLeftPoint, lineColor) self.cameraLines:AddLine(bottomLeftPoint, topLeftPoint, lineColor)
9 Comments
Birdlover 25 May, 2014 @ 6:03am 
thanks alot you're the best <3
skill issue 18 Mar, 2013 @ 11:07pm 
I see. Well, that's too bad. I thought it was similar to TF2 where it's relatively simple to edit positioning, size and look or countless HUD elements. Thanks anyway.
Huze  [author] 18 Mar, 2013 @ 10:01pm 
That kind of thing wouldn't be too difficult, but you wouldn't be able to play on any server if you modded the game that way. Consistency checks make sure you don't edit any of your lua scripts. (If you could edit the lua script, it would be super easy to wallhack/aimbot)

This tutorial is more for if you're making a GUI for a larger scale standalone mod that would be supported by the server.
skill issue 18 Mar, 2013 @ 11:16am 
Nice guide. Coming from TF2, I'm used to heavily customized HUDs. I'm using a big resolution (2560x1440) and I would like to enlarge health and armor bars and move them more towards the center of the screen. How would I go about doing that without getting too much into other details? All of this info is quite overwhelming.
dro 14 Mar, 2013 @ 10:34am 
Thanks!
Huze  [author] 14 Mar, 2013 @ 12:35am 
I'll start adding snippets. I'd recommend just look at some GUI code though. Anything prefixed "GUIInsight_" was made by me and uses all of this stuff.
dro 11 Mar, 2013 @ 1:11pm 
I love this...


Can you please put a snipet of example code of a simple GUI element with comments?
Rehevkor 10 Mar, 2013 @ 11:30am 
Perhaps the syckest DIY'er yet.
McGlaspie  [developer] 8 Mar, 2013 @ 8:01pm 
This is fantastic Huze. This is preciously the kind of thing NS2 modding needs. Documentation. Thank you for spending the time to write this up! :)