Advertisement
hhjfdgdfgdfg

NUI Stuff

Mar 26th, 2024
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.81 KB | None | 0 0
  1. Fullscreen NUI
  2. The most common use case of NUI is a full-screen 'UI page', which is overlaid on top of the game and may or may not have input focus. These are supported on both FiveM and RedM at this time, and are part of basic Citizen framework level support.
  3.  
  4. The following natives are related to using full-screen NUI:
  5.  
  6. SEND_NUI_MESSAGE
  7. SET_NUI_FOCUS
  8. Setting up a fullscreen NUI page
  9. To assign a full-screen NUI page to a resource, currently you need to specify a single ui_page in the resource manifest for the resource containing an UI page, like shown below:
  10.  
  11. -- specify the root page, relative to the resource
  12. ui_page 'main.html'
  13.  
  14. -- every client-side file still needs to be added to the resource packfile!
  15. files {
  16. 'main.html',
  17. 'build/main.js',
  18. }
  19.  
  20. -- a page can also be hosted externally
  21. ui_page 'https://ui-frontend.cfx.example.com/b20210501/index.html'
  22.  
  23. Referencing other assets
  24. The NUI system registers a https://cfx-nui- protocol scope for resource files. Therefore, you can reference a file in a resource as follows:
  25.  
  26. <script type="text/javascript" src="https://cfx-nui-my-resource/production.js" async></script>
  27.  
  28. This formerly was known as nui://, but this is no longer a secure context in newer browser versions.
  29.  
  30. Developer tools
  31. CEF remote debugging tools are exposed on http://localhost:13172/ as long as the game is running. You can use any Chromium-based browser to easily access these tools.
  32.  
  33. Alternately, it can be opened using the nui_devTools command in the game's F8 console, assuming the developer mode is enabled.
  34.  
  35. NUI focus
  36. There's a limited focus stack for NUI resources, you can set focus to the current resource using the SET_NUI_FOCUS native, which will set keyboard focus and/or mouse cursor focus depending on the provided arguments.
  37.  
  38. The most recently focused resource will be ordered on top of the focus stack, and resources are currently implemented as full-screen iframes: that means there's no click-through across resources.
  39.  
  40. NUI messages
  41. You can send a message to the current resource's NUI page using the convenience wrapper SendNUIMessage which encodes a JSON string for you.
  42. For example:
  43.  
  44. -- Lua
  45. SendNUIMessage({
  46. type = 'open'
  47. })
  48.  
  49. // browser side
  50. window.addEventListener('message', (event) => {
  51. if (event.data.type === 'open') {
  52. doOpen();
  53. }
  54. });
  55.  
  56. Direct-rendered UI
  57. In FiveM, you can also render NUI to a runtime texture, which is called DUI for 'direct NUI'. The following natives help with this:
  58.  
  59. CREATE_DUI
  60. CREATE_RUNTIME_TEXTURE_FROM_DUI_HANDLE
  61. DESTROY_DUI
  62. GET_DUI_HANDLE
  63. IS_DUI_AVAILABLE
  64. SEND_DUI_MESSAGE
  65. SEND_DUI_MOUSE_DOWN
  66. SEND_DUI_MOUSE_MOVE
  67. SEND_DUI_MOUSE_UP
  68. SEND_DUI_MOUSE_WHEEL
  69. SET_DUI_URL
  70. The native documentation contains information for each of these, but here are some creative use cases for this:
  71.  
  72. Rendering in 2D space using DRAW_SPRITE
  73. Rendering to a game render target object using similar natives.
  74. Rendering arbitrarily in world space using a specialized Scaleform, like in this forum topic.
  75. This can be used to make cinema screens, asynchronous in-game hint overlays, etc. fairly trivially.
  76.  
  77. NUI callbacks
  78. NUI can also send calls back to the game using so-called 'NUI callbacks'. These are currently only fully supported in Lua, other languages can be used but need a bit of a tricky workaround as these predate function references in codegen.
  79.  
  80. Generally, you'll use the RegisterNUICallback function in Lua, and the REGISTER_NUI_CALLBACK_TYPE native along with an event handler in other languages.
  81.  
  82. Both work very similarly, and we'll describe both below:
  83.  
  84. Registering a NUI callback in Lua
  85. RegisterNUICallback('getItemInfo', function(data, cb)
  86. -- POST data gets parsed as JSON automatically
  87. local itemId = data.itemId
  88.  
  89. if not itemCache[itemId] then
  90. cb({ error = 'No such item!' })
  91. return
  92. end
  93.  
  94. -- and so does callback response data
  95. cb(itemCache[itemId])
  96. end)
  97.  
  98. Registering a NUI callback in C#/JS
  99. // JS
  100. RegisterNuiCallbackType('getItemInfo') // register the type
  101.  
  102. // register a magic event name
  103. on('__cfx_nui:getItemInfo', (data, cb) => {
  104. const itemId = data.itemId;
  105.  
  106. if (!itemCache[itemId]) {
  107. cb({ error: 'No such item!' });
  108. return;
  109. }
  110.  
  111. cb(itemCache[itemId]);
  112. });
  113.  
  114. // C#
  115. RegisterNuiCallbackType("getItemInfo"); // register the type
  116.  
  117. // register the event handler with manual marshaling
  118. EventHandlers["__cfx_nui:getItemInfo"] += new Action<IDictionary<string, object>, CallbackDelegate>((data, cb) =>
  119. {
  120. // get itemId from the object
  121. // alternately you could use `dynamic` and rely on the DLR
  122. if (data.TryGetValue("itemId", out var itemIdObj))
  123. {
  124. cb(new
  125. {
  126. error = "Item ID not specified!"
  127. });
  128.  
  129. return;
  130. }
  131.  
  132. // cast away
  133. var itemId = (itemIdObj as string) ?? "";
  134.  
  135. // same as above
  136. if (!ItemCache.TryGetValue(itemId, out Item item))
  137. {
  138. cb(new
  139. {
  140. error = "No such item!"
  141. });
  142.  
  143. return;
  144. }
  145.  
  146. cb(item);
  147. });
  148.  
  149. Invoking the NUI callback
  150. // browser-side JS
  151. fetch(`https://${GetParentResourceName()}/getItemInfo`, {
  152. method: 'POST',
  153. headers: {
  154. 'Content-Type': 'application/json; charset=UTF-8',
  155. },
  156. body: JSON.stringify({
  157. itemId: 'my-item'
  158. })
  159. }).then(resp => resp.json()).then(resp => console.log(resp));
  160.  
  161. To prevent requests from stalling, you have to return the callback at all times - even if containing just an empty object, or {"ok":true}, or similar.
  162.  
  163. Loading screens
  164. A special NUI frame is the frame called loadingScreen, which is shown during loading of FiveM, instead of the default client-side loading screen or the game loading screen, after joining into a server.
  165.  
  166. It is specified similarly to ui_page using loadscreen in the resource manifest:
  167.  
  168. loadscreen 'load.html'
  169.  
  170. file 'load.html'
  171.  
  172. loadscreen 'https://my-server.example.com/loadscreen/'
  173.  
  174. Cursor/input
  175. The loading screen will always be focused for both mouse and keyboard input, however the cursor is not shown by default for legacy reasons.
  176.  
  177. The NUI cursor can be enabled by adding a loadscreen_cursor entry to the resource manifest that contains the loading screen:
  178.  
  179. loadscreen_cursor 'yes'
  180.  
  181. Handover data
  182. Server scripts can specify data pairs to send to the client loading screen using the handover function in the playerConnecting event. This data will be passed to the loading screen in the window.nuiHandoverData property.
  183.  
  184. In addition to data specified by the server, a field named serverAddress is also added with the current IP/port used for the client->server connection.
  185.  
  186. Example
  187. -- Server script
  188. AddEventHandler('playerConnecting', function(_, _, deferrals)
  189. local source = source
  190.  
  191. deferrals.handover({
  192. name = GetPlayerName(source)
  193. })
  194. end)
  195.  
  196. <!-- loading screen page -->
  197. <h1 id="namePlaceholder">Welcome, <span></span></h1>
  198.  
  199. <script type="text/javascript">
  200. window.addEventListener('DOMContentLoaded', () => {
  201. console.log(`You are connecting to ${window.nuiHandoverData.serverAddress}`);
  202.  
  203. // a thing to note is the use of innerText, not innerHTML: names are user input and could contain bad HTML!
  204. document.querySelector('#namePlaceholder > span').innerText = window.nuiHandoverData.name;
  205. });
  206. </script>
  207.  
  208. Lifetime
  209. By default, the loading screen will show until SHUTDOWN_LOADING_SCREEN is called. However, you can also manually control exit lifetime by setting the loadscreen_manual_shutdown 'yes' directive in your resource manifest.
  210.  
  211. When doing so, the following natives become available once scripts start (after game load and connection to network):
  212.  
  213. SEND_LOADING_SCREEN_MESSAGE
  214. SHUTDOWN_LOADING_SCREEN_NUI
  215. This can be used to, say, add a custom fade-out effect from the loading screen to an in-game view, or integrate NUI events with early-game spawn selection UI.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement