Script v1.7.1.0
- AI
- Animals
- Contracts
- Debug
- Economy
- Effects
- Events
- Farms
- GUI
- AnimalScreen
- AnimationElement
- BitmapElement
- BoxLayoutElement
- BreadcrumbsElement
- ButtonElement
- ButtonOverlay
- ChatWindow
- CheckedOptionElement
- ClearElement
- ContextActionDisplay
- DialogElement
- FieldInfoDisplay
- FillLevelsDisplay
- FlowLayoutElement
- FocusManager
- FrameElement
- FrameReferenceElement
- GameInfoDisplay
- GamePausedDisplay
- Gui
- GuiDataSource
- GuiElement
- GuiMixin
- GuiOverlay
- GuiProfile
- GuiSoundPlayer
- GuiTopDownCamera
- GuiUtils
- HUDDisplayElement
- HUDElement
- HUDFrameElement
- HUDPopupMessage
- HUDTextDisplay
- IndexChangeSubjectMixin
- IndexStateElement
- InGameIcon
- IngameMap
- IngameMapElement
- InputGlyphElement
- InputHelpDisplay
- ListElement
- ListItemElement
- MapHotspot
- MapOverlayGenerator
- MixerWagonHUDExtension
- MultiTextOptionElement
- MultiValueTween
- Overlay
- PagingElement
- PlaySampleMixin
- RenderElement
- RoundStatusBar
- ScreenElement
- SettingsModel
- SideNotification
- SliderElement
- SpeakerDisplay
- SpeedMeterDisplay
- StableListElement
- StatusBar
- TabbedMenu
- TabbedMenuFrameElement
- TabbedMenuWithDetails
- TableElement
- TableHeaderElement
- TextElement
- TextInputElement
- TimerElement
- ToggleButtonElement
- TopNotification
- Tween
- TweenSequence
- VehicleHUDExtension
- VehicleSchemaDisplay
- VideoElement
- Handtools
- I3d
- Materials
- Misc
- Objects
- Placeables
- Player
- Shop
- Sounds
- Specializations
- Triggers
- Utils
- Vehicles
- Weather
Engine v1.7.1.0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- XML
- general
Foundation Reference
SpeakerDisplay
DescriptionPlayer speaker display for consoles. Displays currently speaking players for consoles only. This display is used in place of the chat window.Parent
HUDDisplayElementFunctions
- createBackground
- createComponents
- createSpeakerElement
- draw
- getBackgroundPosition
- getHeight
- new
- onChatVisibilityChange
- onMapVisibilityChange
- onMenuVisibilityChange
- setScale
- storeScaledValues
- update
- updateSpeakingState
- updateVisibility
createBackground
DescriptionCreate the background overlay.Definition
createBackground()Code
263 | function SpeakerDisplay.createBackground(hudAtlasPath) |
264 | local posX, posY = SpeakerDisplay.getBackgroundPosition(1) |
265 | local width, height = getNormalizedScreenValues(unpack(SpeakerDisplay.SIZE.SELF)) |
266 | local overlay = Overlay:new(nil, posX, posY, width, height) |
267 | return overlay |
268 | end |
createComponents
DescriptionCreate required display components.Definition
createComponents()Code
295 | function SpeakerDisplay:createComponents(hudAtlasPath) |
296 | local baseX, baseY = SpeakerDisplay.getBackgroundPosition(1) |
297 | |
298 | -- add lines from bottom to top |
299 | local posY = baseY |
300 | for i = 1, self.maxNumPlayers do |
301 | self:createSpeakerElement(hudAtlasPath, baseX, posY, self.lineWidth, self.lineHeight, self.speakerLineElements) |
302 | posY = posY + self.lineHeight |
303 | end |
304 | |
305 | -- add columns from left to right for menu display |
306 | local posX = baseX |
307 | for i = 1, self.maxNumPlayers do |
308 | self:createSpeakerElement(hudAtlasPath, posX, baseY, self.lineWidth, self.lineHeight, self.speakerColumnElements) |
309 | posX = posX + self.lineWidth |
310 | end |
311 | end |
createSpeakerElement
DescriptionCreate a display element for an active speaker for HUD display.Definition
createSpeakerElement()Code
272 | function SpeakerDisplay:createSpeakerElement(hudAtlasPath, leftX, bottomY, width, height, elementArray) |
273 | -- background |
274 | local overlay = Overlay:new(hudAtlasPath, leftX, bottomY, width, height) |
275 | overlay:setUVs(getNormalizedUVs(SpeakerDisplay.UV.LINE)) |
276 | overlay:setColor(unpack(SpeakerDisplay.COLOR.BACKGROUND)) |
277 | local speakerElement = HUDElement:new(overlay) |
278 | self:addChild(speakerElement) |
279 | table.insert(elementArray, speakerElement) |
280 | |
281 | -- speaker icon |
282 | local offX, offY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SPEAKER_ICON) |
283 | local iconWidth, iconHeight = self:scalePixelToScreenVector(SpeakerDisplay.SIZE.SPEAKER_ICON) |
284 | local posX = leftX + offX |
285 | local posY = bottomY + (height - iconHeight) * 0.5 + offY |
286 | overlay = Overlay:new(hudAtlasPath, posX, posY, iconWidth, iconHeight) |
287 | overlay:setUVs(getNormalizedUVs(SpeakerDisplay.UV.SPEAKER_ICON)) |
288 | overlay:setColor(unpack(SpeakerDisplay.COLOR.SPEAKER_ICON)) |
289 | local speakerIconElement = HUDElement:new(overlay) |
290 | speakerElement:addChild(speakerIconElement) |
291 | end |
draw
DescriptionDefinitiondraw()Code
180 | function SpeakerDisplay:draw() |
181 | if self:getVisible() and #self.currentSpeakers > 0 then |
182 | -- make sure we draw on top of everything because this display is so important for PS4 technical requirements: |
183 | new2DLayer() |
184 | |
185 | SpeakerDisplay:superClass().draw(self) -- draw HUD elements |
186 | |
187 | setTextBold(true) |
188 | setTextAlignment(RenderText.ALIGN_LEFT) |
189 | |
190 | local speakerElements = self.speakerLineElements |
191 | local offX, offY = self.textLineOffsetX, self.textLineOffsetY |
192 | if self.isMenuVisible and not self.isMenuMapVisible then |
193 | -- use horizontal elements as the base points when in the menu |
194 | speakerElements = self.speakerColumnElements |
195 | offX, offY = self.textColOffsetX, self.textColOffsetY |
196 | end |
197 | |
198 | -- draw names |
199 | for i = 1, #self.currentSpeakers do |
200 | local speakerElement = speakerElements[i] |
201 | local lineX, lineY = speakerElement:getPosition() |
202 | local lineHeight = speakerElement:getHeight() |
203 | |
204 | local posX = lineX + offX |
205 | local posY = lineY + (lineHeight - self.textSize) * 0.5 + offY + self.textOffsetY |
206 | |
207 | -- render shadow |
208 | setTextColor(unpack(SpeakerDisplay.COLOR.NAME_SHADOW)) |
209 | renderText(posX + self.shadowOffset, posY - self.shadowOffset, self.textSize, self.currentSpeakers[i]) |
210 | -- render text |
211 | setTextColor(unpack(SpeakerDisplay.COLOR.NAME)) |
212 | renderText(posX, posY, self.textSize, self.currentSpeakers[i]) |
213 | end |
214 | end |
215 | end |
getBackgroundPosition
DescriptionGet this element's base background position.Definition
getBackgroundPosition(float uiScale)Arguments
float | uiScale | Current UI scale factor |
231 | function SpeakerDisplay.getBackgroundPosition(uiScale) |
232 | local offX, offY = getNormalizedScreenValues(unpack(SpeakerDisplay.POSITION.SELF)) |
233 | -- make sure that the text is displayed within the center 90% of the screen (PS4 technical requirement): |
234 | -- 0.051 -> 5% in from the bottom (plus safety margin) |
235 | return g_safeFrameOffsetX + offX, math.max(0.51, g_safeFrameOffsetY + offY) |
236 | end |
getHeight
DescriptionDefinitiongetHeight()Code
90 | function SpeakerDisplay:getHeight() |
91 | return #self.currentSpeakers * self.lineHeight |
92 | end |
new
DescriptionCreate a new SpeakerDisplay.Definition
new(string hudAtlasPath, table ingameMap)Arguments
string | hudAtlasPath | Path to the HUD atlas texture. |
table | ingameMap | IngameMap reference for positioning |
table | SpeakerDisplay | instance |
23 | function SpeakerDisplay.new(hudAtlasPath, ingameMap) |
24 | local backgroundOverlay = SpeakerDisplay.createBackground(hudAtlasPath) |
25 | local self = SpeakerDisplay:superClass().new(SpeakerDisplay_mt, backgroundOverlay, nil) |
26 | |
27 | self.ingameMap = ingameMap |
28 | |
29 | self.maxNumPlayers = g_serverMaxCapacity |
30 | self.users = {} |
31 | |
32 | self.isMenuVisible = true |
33 | self.isMenuMapVisible = false |
34 | self.isChatVisible = false |
35 | |
36 | self.userSpeaking = {} -- {"full online ID" = bool} |
37 | self.currentSpeakers = {} -- {i = "full online ID"} |
38 | self.speakerLineElements = {} -- {i = HUDElement} |
39 | self.speakerColumnElements = {} -- {i = HUDElement} |
40 | |
41 | self.mapOffsetX, self.mapOffsetY = 0, 0 |
42 | self.positionHorizontalX, self.positionHorizontalY = 0, 0 |
43 | self.lineWidth, self.lineHeight = 0, 0 |
44 | self.textLineOffsetX, self.textLineOffsetY = 0, 0 |
45 | self.textSize = 0 |
46 | self.textOffsetY = 0 |
47 | self.shadowOffset = 0 |
48 | |
49 | self:storeScaledValues() |
50 | self:createComponents(hudAtlasPath) |
51 | |
52 | return self |
53 | end |
onChatVisibilityChange
DescriptionHandle chat message visibility state changeDefinition
onChatVisibilityChange()Code
82 | function SpeakerDisplay:onChatVisibilityChange(isChatVisible) |
83 | self.isChatVisible = isChatVisible |
84 | |
85 | self:updateVisibility() |
86 | end |
onMapVisibilityChange
DescriptionHandle map visibility change. The in-game menu map needs this display to be showing speakers in regular vertical layouting mode, therefore we need to know when it is active.Definition
onMapVisibilityChange()Code
66 | function SpeakerDisplay:onMapVisibilityChange(isMapVisible) |
67 | self.isMenuMapVisible = isMapVisible |
68 | self:updateVisibility() |
69 | end |
onMenuVisibilityChange
DescriptionHandle menu visibility state change.Definition
onMenuVisibilityChange()Code
73 | function SpeakerDisplay:onMenuVisibilityChange(isMenuVisible, isOverlayMenu) |
74 | self.isMenuVisible = isMenuVisible and not isOverlayMenu |
75 | self.isMenuMapVisible = self.isMenuMapVisible and isMenuVisible |
76 | |
77 | self:updateVisibility() -- makes sure there is no one-frame delay for the re-ordering (vertical/horizontal) |
78 | end |
setScale
DescriptionSet this element's UI scale.Definition
setScale()Code
223 | function SpeakerDisplay:setScale(uiScale) |
224 | SpeakerDisplay:superClass().setScale(self, uiScale) |
225 | self:storeScaledValues() |
226 | end |
storeScaledValues
DescriptionStore scaled positioning, size and offset values.Definition
storeScaledValues()Code
240 | function SpeakerDisplay:storeScaledValues() |
241 | self.mapOffsetX, self.mapOffsetY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SELF) |
242 | self.positionHorizontalX, self.positionHorizontalY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SELF_HORIZONTAL) |
243 | self.lineWidth, self.lineHeight = self:scalePixelToScreenVector(SpeakerDisplay.SIZE.LINE) |
244 | |
245 | self.textLineOffsetX, self.textLineOffsetY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.NAME) |
246 | self.textColOffsetX, self.textColOffsetY = self.textLineOffsetX, self.textLineOffsetY |
247 | local selfLeftX = self:getPosition() |
248 | -- make sure that the text is displayed within the center 90% of the screen (PS4 technical requirement): |
249 | -- 0.051 -> 5% in from the left (plus safety margin), subtract display position because we are changing an offset |
250 | self.textLineOffsetX = math.max(0.051 - selfLeftX, self.textLineOffsetX) |
251 | |
252 | self.textSize = self:scalePixelToScreenHeight(SpeakerDisplay.TEXT_SIZE.NAME) |
253 | self.textOffsetY = self.textSize * 0.15 |
254 | self.shadowOffset = SpeakerDisplay.SHADOW_OFFSET_FACTOR * self.textSize |
255 | end |
update
DescriptionUpdate the display state each frame.Definition
update()Code
149 | function SpeakerDisplay:update(dt) |
150 | SpeakerDisplay:superClass().update(self, dt) |
151 | |
152 | self:updateSpeakingState() |
153 | self:updateVisibility() |
154 | |
155 | -- update position based on mini-map, this display must never be obstructed or obstruct anything else (PS4 requirement) |
156 | if not self.isMenuVisible or self.isMenuMapVisible then |
157 | local mapHeight = 0 |
158 | local offsetY = (1 - self:getHeight()) * 0.5 |
159 | if not self.isMenuMapVisible then |
160 | mapHeight = self.ingameMap:getHeight() |
161 | offsetY = mapHeight > 0 and self.mapOffsetY or 0 -- only add offset if the HUD map is visible (height > 0) |
162 | end |
163 | |
164 | local posX = g_safeFrameOffsetX + self.mapOffsetX |
165 | local posY = math.max(0.051, g_safeFrameOffsetY + mapHeight + offsetY) -- always within 90% of screen |
166 | self:setPosition(posX, posY) |
167 | else |
168 | local posX = math.max(0.051, self.positionHorizontalX) |
169 | local posY = math.max(0.051, self.positionHorizontalY) |
170 | self:setPosition(posX, posY) |
171 | end |
172 | end |
updateSpeakingState
DescriptionUpdate current speaking state for all connected users.Definition
updateSpeakingState()Code
100 | function SpeakerDisplay:updateSpeakingState() |
101 | for _, user in pairs(self.users) do |
102 | local wasSpeakingLastFrame = self.userSpeaking[user:getPlatformUserId()] |
103 | local isSpeakingNow = meshNetworkGetNodeStatusForApp(user:getPlatformNodeId() or "", "voice") > 0 |
104 | |
105 | if wasSpeakingLastFrame and not isSpeakingNow then |
106 | for i, userId in ipairs(self.currentSpeakers) do |
107 | if userId == user:getNickname() then |
108 | table.remove(self.currentSpeakers, i) |
109 | break |
110 | end |
111 | end |
112 | elseif isSpeakingNow and not wasSpeakingLastFrame then |
113 | table.insert(self.currentSpeakers, user:getNickname()) |
114 | end |
115 | |
116 | self.userSpeaking[user:getPlatformUserId()] = isSpeakingNow |
117 | end |
118 | end |
updateVisibility
DescriptionUpdate visibility states based on active speakers.Definition
updateVisibility()Code
122 | function SpeakerDisplay:updateVisibility() |
123 | local useLines = not self.isMenuVisible or self.isMenuMapVisible |
124 | local anyVisible = false |
125 | for i = 1, self.maxNumPlayers do |
126 | local lineVisible = i <= #self.currentSpeakers |
127 | self.speakerLineElements[i]:setVisible(lineVisible and useLines) |
128 | self.speakerColumnElements[i]:setVisible(lineVisible and not useLines) |
129 | |
130 | anyVisible = anyVisible or lineVisible |
131 | end |
132 | |
133 | self:setVisible(anyVisible) |
134 | |
135 | if anyVisible then |
136 | local color = SpeakerDisplay.COLOR.BACKGROUND |
137 | if self.isMenuMapVisible or self.isChatVisible then |
138 | color = SpeakerDisplay.COLOR.BACKGROUND_HIGH_CONTRAST |
139 | end |
140 | |
141 | for _, lineElement in pairs(self.speakerLineElements) do |
142 | lineElement:setColor(unpack(color)) |
143 | end |
144 | end |
145 | end |