Difference between revisions of "Lua/CustomHudElements"

From Serious Sam Wiki
< Lua
Jump to: navigation, search
(Example: Updated tutorial to Serious Sam Fusion version.)
m (Example)
Line 35: Line 35:
     -- eeViewerChanged : CViewerChangedScriptEvent
     -- eeViewerChanged : CViewerChangedScriptEvent

Revision as of 11:21, 30 August 2019


Warning 16x16.png Warning: This tutorial is outdated for Serious Engine 2017 and also needs complete rewriting. Contact Asdolg if you can provide up-to-date knowledge.

A Heads-Up Display (HUD) is a collection of elements which are rendered as an overlay over the scene, and convey useful information to the player. In SeriousEngine, these HUD elements may render 2D images, text, or even fully animated and shaded 3D models. A HUD element is defined by its params, which can be created in the Editor by editing the HudParams.rsc database file found in project's content directory, e.g. "Content/SeriousSam3/Databases/HudParams.rsc". For each params added into the database, a new HUD element is automatically created and managed by the HUD.

There is a limited number of available predefined HUD element types implemented in native code. Most of these are fully native and non-scriptable, and feature large-scale design. What this means is that there is a specific HUD element for an entire gameplay feature, e.g., player's health, player's deathmatch score (frags, deaths), etc. A different design would be to offer just simple, atomic, reusable generic elements such as icons, bars, text boxes, etc., and then have scripts combine these to create custom HUDs. This is still under development, but precisely this approach is now available as well, through two new HUD element types which are fully scriptable: TextBox and Model.

Note that it is still not possible to actually create a new HUD element from scratch in a script. It is still necessary to add params for all the HUD elements ever possibly needed, and have them created automatically. However, it is now possible to access and control these elements from scripts: show or hide them, move and animate them, update their exposed properties, etc.


For this example, we'll assume you've added params for a text box, and named this element "ExampleTextBox". We'll show how to get the current viewer (the player for which the scene is rendered), and how to get the current viewer's HUD and its elements.

To begin with, we'll have to listen for ViewerChanged events. These events are sent each time the local viewer changes, for example, the user switches spectated player, joins with its own player, etc. This is important, as each player owns their own HUD, and the script must be aware of which HUD is actually being rendered. The ViewerChanged event is also sent when the local viewer is lost, such as when the user spectates from a camera, rather than another player. In our example, both cases are handled gracefully in the function UpdateOwner(). This function will cache the current owner, as well as all the required HUD elements. If there is no owner, however, it just clears the cache. A HUD element can be retrieved from the owner by searching for it using its unique name defined in its params (if there are multiple HUD elements sharing the same name, only the first one can be retrieved). This is a simple linear search, so caching the results is a good approach, performance-wise.

Once our HUD elements cache is prepared, we can control the HUD as desired. A simple approach is to listen for global OnStep events, check if the cache is valid, and if so, update properties on HUD elements. In the example below, we retrieve the player's name and health, and show this information in the text box.

local owner = nil -- owner : CPlayerPuppetEntity
local textBox = nil -- textBox : CTextBoxHudElement

local function UpdateOwner(player)
  textBox = nil  
  owner = player
  if not(owner == nil) then
    textBox = owner:FindHudElementByName("ExampleTextBox")

    -- eeViewerChanged : CViewerChangedScriptEvent
      local viewer = eeViewerChanged:GetViewer()
    -- eeOnStep : COnStepScriptEvent
      if not(IsDeleted(owner) or IsDeleted(textBox)) then
        local health = owner:GetHealth()
        textBox:SetText(owner:GetPlayerName() .. ": " .. health .. " HP")
Tip:  HUD is by definition a purely local effect, which each client is expected to maintain for themselves. Therefore, scripts augmenting the HUD should be set to execute on both server and client (the default being to execute on server only).