@3dsource/angular-unreal-module 0.0.157 → 0.0.159
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,392 +1,185 @@
|
|
|
1
1
|
# @3dsource/angular-unreal-module
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Standalone Angular integration for Unreal Engine Pixel Streaming. The package
|
|
4
|
+
provides the scene component, WebRTC and signalling lifecycle, NgRx state,
|
|
5
|
+
command/callback APIs, reconnection, file transfer and telemetry.
|
|
4
6
|
|
|
5
|
-
##
|
|
7
|
+
## Requirements
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- Standalone Unreal scene component to embed UE stream
|
|
10
|
-
- Communication bridge (commands, UI interactions, input data)
|
|
11
|
-
- Callback listener for Unreal events and command responses
|
|
12
|
-
- NgRx state and effects for 3D stream lifecycle
|
|
13
|
-
- Config and utilities for telemetry, errors, and regions ping
|
|
14
|
-
- Auto-reconnection support for WebRTC/DataChannel failures
|
|
15
|
-
- File receiving from Unreal Engine
|
|
16
|
-
- Analytics, FPS monitoring, and stream status telemetry
|
|
17
|
-
- Playwright testing mode with mock services
|
|
18
|
-
|
|
19
|
-
## Installation
|
|
20
|
-
|
|
21
|
-
### Prerequisites
|
|
22
|
-
|
|
23
|
-
- Angular `>=19.0.0 <23.0.0`
|
|
24
|
-
- NgRx store and effects `>=19.0.0 <23.0.0`
|
|
25
|
-
- Angular CDK `>=19.0.0 <23.0.0` — used for dialog overlays
|
|
9
|
+
- Angular, Angular CDK and Angular Forms `>=19.0.0 <23.0.0`
|
|
10
|
+
- NgRx Store and Effects `>=19.0.0 <23.0.0`
|
|
26
11
|
- RxJS `>=7.8.0 <8.0.0`
|
|
27
|
-
- `
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
This library requires the following peer dependencies:
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{
|
|
35
|
-
"@3dsource/source-ui-native": ">=1.0.9",
|
|
36
|
-
"@3dsource/types-unreal": ">=0.0.7",
|
|
37
|
-
"@3dsource/utils": ">=1.0.21",
|
|
38
|
-
"@angular/cdk": ">=19.0.0 <23.0.0",
|
|
39
|
-
"@angular/common": ">=19.0.0 <23.0.0",
|
|
40
|
-
"@angular/core": ">=19.0.0 <23.0.0",
|
|
41
|
-
"@angular/forms": ">=19.0.0 <23.0.0",
|
|
42
|
-
"@angular/platform-browser": ">=19.0.0 <23.0.0",
|
|
43
|
-
"@ngrx/effects": ">=19.0.0 <23.0.0",
|
|
44
|
-
"@ngrx/store": ">=19.0.0 <23.0.0",
|
|
45
|
-
"rxjs": ">=7.8.0 <8.0.0"
|
|
46
|
-
}
|
|
47
|
-
```
|
|
12
|
+
- `@3dsource/source-ui-native >=1.0.9`
|
|
13
|
+
- `@3dsource/types-unreal >=0.0.7`
|
|
14
|
+
- `@3dsource/utils >=1.0.21`
|
|
15
|
+
- `provideHttpClient()` in the host application
|
|
48
16
|
|
|
49
|
-
|
|
17
|
+
## Installation
|
|
50
18
|
|
|
51
19
|
```shell
|
|
52
|
-
|
|
20
|
+
pnpm add @3dsource/angular-unreal-module @3dsource/source-ui-native @3dsource/types-unreal @3dsource/utils
|
|
53
21
|
```
|
|
54
22
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
The API is fully standalone (no NgModule). Use providers and components as shown below.
|
|
23
|
+
The package is standalone and does not expose an NgModule.
|
|
58
24
|
|
|
59
|
-
|
|
25
|
+
## Setup
|
|
60
26
|
|
|
61
|
-
|
|
27
|
+
### 1. Register state and configuration once
|
|
62
28
|
|
|
63
|
-
|
|
29
|
+
Add the Unreal feature state, HTTP client and configuration at the application
|
|
30
|
+
root. `UNREAL_CONFIG` is required, although all its fields are optional.
|
|
64
31
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
import { provideRouter } from '@angular/router';
|
|
32
|
+
<!-- prettier-ignore -->
|
|
33
|
+
```typescript
|
|
68
34
|
import { provideHttpClient } from '@angular/common/http';
|
|
35
|
+
import type { ApplicationConfig } from '@angular/core';
|
|
69
36
|
import { provideStore } from '@ngrx/store';
|
|
70
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
provideUnrealState,
|
|
39
|
+
UNREAL_CONFIG,
|
|
40
|
+
type UnrealInitialConfig,
|
|
41
|
+
} from '@3dsource/angular-unreal-module';
|
|
42
|
+
|
|
43
|
+
const unrealConfig = {
|
|
44
|
+
regionsPingUrl: 'https://datacenter.3dsource.com/regions/',
|
|
45
|
+
dataChannelConnectionTimeout: 8000,
|
|
46
|
+
fpsMonitor: false,
|
|
47
|
+
autoHighResolution: false,
|
|
48
|
+
} satisfies UnrealInitialConfig;
|
|
71
49
|
|
|
72
50
|
export const appConfig: ApplicationConfig = {
|
|
73
51
|
providers: [
|
|
74
|
-
provideRouter([]),
|
|
75
52
|
provideHttpClient(),
|
|
76
|
-
|
|
77
|
-
// Root NgRx (if not already added in your app)
|
|
78
53
|
provideStore(),
|
|
79
54
|
provideUnrealState(),
|
|
80
|
-
|
|
81
|
-
// Required: Unreal initial configuration
|
|
82
|
-
{
|
|
83
|
-
provide: UNREAL_CONFIG,
|
|
84
|
-
useValue: {
|
|
85
|
-
customErrorsEndpoint: '', // Endpoint for custom error reporting
|
|
86
|
-
commandTelemetryReceiver: '', // Endpoint for command telemetry
|
|
87
|
-
regionsPingUrl: '', // URL prefix for regions latency ping
|
|
88
|
-
screenLockerContainerId: '', // DOM container id for screen locker overlay
|
|
89
|
-
dataChannelConnectionTimeout: 8000, // Timeout in ms for data channel connection (default: 8000)
|
|
90
|
-
streamTelemetryV2Url: '', // Endpoint for stream-status telemetry
|
|
91
|
-
fpsMonitor: false, // Enable FPS monitoring
|
|
92
|
-
autoHighResolution: false, // Raise resolution after the scene becomes idle
|
|
93
|
-
playwright: false, // Mirrors the provider flag for services/effects
|
|
94
|
-
},
|
|
95
|
-
},
|
|
55
|
+
{ provide: UNREAL_CONFIG, useValue: unrealConfig },
|
|
96
56
|
],
|
|
97
57
|
};
|
|
98
58
|
```
|
|
99
59
|
|
|
100
|
-
|
|
60
|
+
Omit `provideStore()` when the root NgRx store is already configured.
|
|
101
61
|
|
|
102
|
-
|
|
62
|
+
Available configuration fields:
|
|
103
63
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
64
|
+
| Field | Purpose |
|
|
65
|
+
| ------------------------------ | ---------------------------------------------- |
|
|
66
|
+
| `regionsPingUrl` | Region latency endpoint |
|
|
67
|
+
| `dataChannelConnectionTimeout` | DataChannel connection timeout in ms |
|
|
68
|
+
| `customErrorsEndpoint` | Custom error reporting endpoint |
|
|
69
|
+
| `commandTelemetryReceiver` | Command telemetry endpoint |
|
|
70
|
+
| `streamTelemetryV2Url` | Stream lifecycle telemetry endpoint |
|
|
71
|
+
| `screenLockerContainerId` | Container used by the screen-locker overlay |
|
|
72
|
+
| `fpsMonitor` | Enables FPS monitoring |
|
|
73
|
+
| `autoHighResolution` | Raises resolution after the scene becomes idle |
|
|
74
|
+
| `playwright` | Enables the test-specific service behaviour |
|
|
75
|
+
|
|
76
|
+
Use `{ provide: UNREAL_CONFIG, useValue: {} }` for the minimal configuration.
|
|
108
77
|
|
|
109
|
-
|
|
110
|
-
itself is required. Available fields are `playwright`,
|
|
111
|
-
`customErrorsEndpoint`, `commandTelemetryReceiver`, `regionsPingUrl`,
|
|
112
|
-
`screenLockerContainerId`, `dataChannelConnectionTimeout`,
|
|
113
|
-
`streamTelemetryV2Url`, `fpsMonitor` and `autoHighResolution`.
|
|
78
|
+
### 2. Boot the engine on a lazy route
|
|
114
79
|
|
|
115
|
-
|
|
80
|
+
Lazy-load the route file from the application router:
|
|
81
|
+
|
|
82
|
+
<!-- prettier-ignore -->
|
|
83
|
+
```typescript
|
|
84
|
+
import type { Routes } from '@angular/router';
|
|
85
|
+
|
|
86
|
+
export const APP_ROUTES: Routes = [
|
|
87
|
+
{
|
|
88
|
+
path: 'stream',
|
|
89
|
+
loadChildren: () =>
|
|
90
|
+
import('./stream/stream.routes').then((module) => module.STREAM_ROUTES),
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
```
|
|
116
94
|
|
|
117
|
-
`provideUnrealModule()`
|
|
118
|
-
services. Put it on every lazy route that renders a 3D scene:
|
|
95
|
+
Register `provideUnrealModule()` inside that lazy route file:
|
|
119
96
|
|
|
120
|
-
|
|
121
|
-
|
|
97
|
+
<!-- prettier-ignore -->
|
|
98
|
+
```typescript
|
|
99
|
+
import type { Routes } from '@angular/router';
|
|
122
100
|
import { provideUnrealModule } from '@3dsource/angular-unreal-module';
|
|
101
|
+
import { StreamComponent } from './stream.component';
|
|
123
102
|
|
|
124
103
|
export const STREAM_ROUTES: Routes = [
|
|
125
104
|
{
|
|
126
|
-
path: '
|
|
127
|
-
|
|
105
|
+
path: '',
|
|
106
|
+
component: StreamComponent,
|
|
128
107
|
providers: [provideUnrealModule()],
|
|
129
108
|
},
|
|
130
109
|
];
|
|
131
110
|
```
|
|
132
111
|
|
|
133
|
-
Keep `provideUnrealState()` and `UNREAL_CONFIG` at the root.
|
|
134
|
-
`
|
|
135
|
-
|
|
112
|
+
Keep `provideUnrealState()` and `UNREAL_CONFIG` at the application root.
|
|
113
|
+
The `loadChildren()` boundary keeps the streaming engine out of the initial
|
|
114
|
+
bundle. Route-scoping `provideUnrealModule()` tears down its effects when the
|
|
115
|
+
route is left.
|
|
136
116
|
|
|
137
|
-
### 3
|
|
117
|
+
### 3. Render the scene
|
|
138
118
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
```ts
|
|
142
|
-
import { Component } from '@angular/core';
|
|
119
|
+
```typescript
|
|
120
|
+
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
143
121
|
import { UnrealSceneComponent } from '@3dsource/angular-unreal-module';
|
|
144
122
|
|
|
145
123
|
@Component({
|
|
146
|
-
selector: 'app-
|
|
147
|
-
standalone: true,
|
|
124
|
+
selector: 'app-stream',
|
|
148
125
|
imports: [UnrealSceneComponent],
|
|
149
|
-
template:
|
|
126
|
+
template: `<app-unreal-scene />`,
|
|
127
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
150
128
|
})
|
|
151
|
-
export class
|
|
152
|
-
onHover(isOver: boolean) {
|
|
153
|
-
// handle mouse over scene
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
Component selector: `<app-unreal-scene>`
|
|
159
|
-
|
|
160
|
-
Inputs:
|
|
161
|
-
|
|
162
|
-
| Input | Type | Default |
|
|
163
|
-
| ---------------------------- | ----------------------------------- | ------------------------------- |
|
|
164
|
-
| `isStudio` | `boolean` | `false` |
|
|
165
|
-
| `useContainerAsSizeProvider` | `boolean` | `true` |
|
|
166
|
-
| `resolutionSize` | `{ width: number; height: number }` | `{ width: 1920, height: 1080 }` |
|
|
167
|
-
|
|
168
|
-
Outputs:
|
|
169
|
-
|
|
170
|
-
| Output | Type |
|
|
171
|
-
| ---------------------- | --------------------------- |
|
|
172
|
-
| `changeMouseOverScene` | `OutputEmitterRef<boolean>` |
|
|
173
|
-
|
|
174
|
-
### 4) Send commands / interactions to Unreal
|
|
175
|
-
|
|
176
|
-
Inject `UnrealCommunicatorService` to send commands or UI interactions. Types for command packets are provided by `@3dsource/types-unreal`.
|
|
177
|
-
|
|
178
|
-
There are three sending methods — choose based on your needs:
|
|
179
|
-
|
|
180
|
-
| Method | Description |
|
|
181
|
-
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
182
|
-
| `sendCommandToUnreal` | Full pipeline: adds `correlationId`, records telemetry, dispatches NgRx `commandStarted` action. **Recommended for application commands.** |
|
|
183
|
-
| `emitUIInteraction` | Sends the packet as a raw `UIInteraction` message. No telemetry or store dispatch. |
|
|
184
|
-
| `emitCommand` | Sends the packet as a raw `Command` message (for console commands, resolution changes, etc.). |
|
|
185
|
-
|
|
186
|
-
```ts
|
|
187
|
-
import { Component, inject } from '@angular/core';
|
|
188
|
-
import { UnrealCommunicatorService } from '@3dsource/angular-unreal-module';
|
|
189
|
-
import { MetaBoxCommand } from '@3dsource/types-unreal';
|
|
190
|
-
import type { MetaBoxCommandPacket } from '@3dsource/types-unreal';
|
|
191
|
-
|
|
192
|
-
@Component({ standalone: true, template: '' })
|
|
193
|
-
export class MyComponent {
|
|
194
|
-
private unreal = inject(UnrealCommunicatorService);
|
|
195
|
-
|
|
196
|
-
sendSomeCommand() {
|
|
197
|
-
// Recommended: use sendCommandToUnreal for full telemetry + store tracking
|
|
198
|
-
this.unreal.sendCommandToUnreal({
|
|
199
|
-
command: MetaBoxCommand.FChangeResolutionCommand,
|
|
200
|
-
payload: { resolution: { x: 1920, y: 1080 } },
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
sendRawUIInteraction() {
|
|
205
|
-
// Low-level: sends UIInteraction message without telemetry tracking
|
|
206
|
-
const packet = {
|
|
207
|
-
command: 'CustomCommand',
|
|
208
|
-
payload: { key: 'value' },
|
|
209
|
-
} as MetaBoxCommandPacket;
|
|
210
|
-
this.unreal.emitUIInteraction(packet);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### 5) Store integration (actions & selectors)
|
|
216
|
-
|
|
217
|
-
`provideUnrealState()` registers the NgRx feature state `unrealFeature`. You
|
|
218
|
-
can dispatch actions and select state in your components:
|
|
219
|
-
|
|
220
|
-
```ts
|
|
221
|
-
import { inject } from '@angular/core';
|
|
222
|
-
import { Store } from '@ngrx/store';
|
|
223
|
-
import { disconnectStream, selectShowLoader, selectTotalProgress, setConfig, setOrchestrationContext, startStream, unrealFeature } from '@3dsource/angular-unreal-module';
|
|
224
|
-
|
|
225
|
-
// Dispatch actions
|
|
226
|
-
const store = inject(Store);
|
|
227
|
-
store.dispatch(startStream({ config: { autoStart: true, warnTimeout: 120 } }));
|
|
228
|
-
|
|
229
|
-
// Select state
|
|
230
|
-
const progress = store.selectSignal(selectTotalProgress);
|
|
231
|
-
const isVideoPlaying = store.selectSignal(unrealFeature.selectIsVideoPlaying);
|
|
232
|
-
const dataChannelConnected = store.selectSignal(unrealFeature.selectDataChannelConnected);
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
**Key selectors:**
|
|
236
|
-
|
|
237
|
-
- `selectTotalProgress` — Scene load progress (0–1 float)
|
|
238
|
-
- `selectShowLoader` — Whether loader screen should be visible
|
|
239
|
-
- `selectShowReconnectPopup` — Whether reconnect popup should be shown
|
|
240
|
-
- `selectIsVideoPlayingAndDataChannelConnected` — Combined readiness check
|
|
241
|
-
- `selectStreamConfig` — Current stream configuration
|
|
242
|
-
- `unrealFeature.selectCirrusConnected` — Signalling server connection status
|
|
243
|
-
- `unrealFeature.selectDataChannelConnected` — Data channel status
|
|
244
|
-
- `unrealFeature.selectViewportReady` — Viewport readiness
|
|
245
|
-
|
|
246
|
-
**Key actions:**
|
|
247
|
-
|
|
248
|
-
- `startStream` — Start streaming with config
|
|
249
|
-
- `setConfig` — Update stream configuration
|
|
250
|
-
- `setOrchestrationContext` — Set orchestration URLs and environment
|
|
251
|
-
- `disconnectStream` — Disconnect with reason
|
|
252
|
-
- `destroyUnrealScene` — Full teardown
|
|
253
|
-
- `reconnectPeer` — Trigger peer reconnection
|
|
254
|
-
|
|
255
|
-
### 6) Listen for Unreal callbacks
|
|
256
|
-
|
|
257
|
-
Inject `UnrealCallbackService` to listen for callback events from Unreal Engine and to observe command responses.
|
|
258
|
-
|
|
259
|
-
There are two methods:
|
|
260
|
-
|
|
261
|
-
| Method | Description |
|
|
262
|
-
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
263
|
-
| `fromUnrealCallback` | Listens for callbacks matching a command or event key. Supports MetaBox commands and custom Unreal callback events. Returns `Observable<UnrealCallbackDescriptor[K]>`. |
|
|
264
|
-
| `observeCommandResponse` | Sends a command and waits for its matching response by `correlationId`. Returns `Observable<MetaBoxCommandList[K]>`. Includes timeout and error handling. |
|
|
265
|
-
|
|
266
|
-
**Custom Unreal callback events** (defined in `UnrealCallbackEventMap`):
|
|
267
|
-
|
|
268
|
-
| Event | Payload Type |
|
|
269
|
-
| -------------------------- | --------------------------------------------------- |
|
|
270
|
-
| `onSceneState` | `FSceneState` |
|
|
271
|
-
| `onFocusObject` | `FProductPayload` |
|
|
272
|
-
| `cameraChanged` | `FCameraChangedPayload` |
|
|
273
|
-
| `onObjectTransformChanged` | `{ objectName: string; transform: FTransformJson }` |
|
|
274
|
-
| `onChangeSequence` | `unknown` |
|
|
275
|
-
| `onFinishedSequence` | `unknown` |
|
|
276
|
-
|
|
277
|
-
```ts
|
|
278
|
-
import { Component, inject } from '@angular/core';
|
|
279
|
-
import { UnrealCallbackService } from '@3dsource/angular-unreal-module';
|
|
280
|
-
import { UnrealCommunicatorService } from '@3dsource/angular-unreal-module';
|
|
281
|
-
import { MetaBoxCommand } from '@3dsource/types-unreal';
|
|
282
|
-
|
|
283
|
-
@Component({ standalone: true, template: '' })
|
|
284
|
-
export class MyComponent {
|
|
285
|
-
private callbackService = inject(UnrealCallbackService);
|
|
286
|
-
private communicator = inject(UnrealCommunicatorService);
|
|
287
|
-
|
|
288
|
-
listenForCallbacks() {
|
|
289
|
-
// Listen for a MetaBox command callback
|
|
290
|
-
this.callbackService.fromUnrealCallback(MetaBoxCommand.FLoadProductCommand).subscribe((data) => console.log('Product loaded:', data));
|
|
291
|
-
|
|
292
|
-
// Listen for a custom Unreal event
|
|
293
|
-
this.callbackService.fromUnrealCallback('cameraChanged').subscribe((data) => console.log('Camera changed:', data));
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
sendAndObserve() {
|
|
297
|
-
// Send a command and observe its response (with correlationId matching)
|
|
298
|
-
this.callbackService
|
|
299
|
-
.observeCommandResponse(
|
|
300
|
-
{ command: MetaBoxCommand.FLoopBackCommand },
|
|
301
|
-
(data) => this.communicator.sendCommandToUnreal(data),
|
|
302
|
-
60000, // timeout in ms (default: 60000)
|
|
303
|
-
true, // emit on timeout (default: true)
|
|
304
|
-
)
|
|
305
|
-
.subscribe((response) => console.log('Response:', response));
|
|
306
|
-
}
|
|
307
|
-
}
|
|
129
|
+
export class StreamComponent {}
|
|
308
130
|
```
|
|
309
131
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
| Pipe | Description |
|
|
351
|
-
| ---------- | ------------------------------------------------------------ |
|
|
352
|
-
| `SafePipe` | Sanitizes a value for the requested Angular security context |
|
|
353
|
-
|
|
354
|
-
### Interfaces
|
|
355
|
-
|
|
356
|
-
| Interface | Description |
|
|
357
|
-
| -------------------------- | ---------------------------------------------------------------------------- |
|
|
358
|
-
| `UnrealInitialConfig` | Shape for `UNREAL_CONFIG` injection token |
|
|
359
|
-
| `StreamConfig` | Stream configuration (autoStart, warnTimeout) |
|
|
360
|
-
| `StreamResolutionProps` | Stream resolution width/height |
|
|
361
|
-
| `UnrealCallbackEventMap` | Custom Unreal callback events pushed from Unreal via data channel |
|
|
362
|
-
| `UnrealCallbackDescriptor` | Combined map of MetaBoxCommandList and UnrealCallbackEventMap callback types |
|
|
363
|
-
|
|
364
|
-
## Features
|
|
365
|
-
|
|
366
|
-
- Standalone Unreal Scene Component
|
|
367
|
-
- Command and UI Interaction API via `UnrealCommunicatorService`
|
|
368
|
-
- Callback listener and command response observer via `UnrealCallbackService`
|
|
369
|
-
- Event-driven status UI (freeze frame, video stats, play overlay, AFK, low bandwidth)
|
|
370
|
-
- NgRx-powered state management and effects
|
|
371
|
-
- **Required** initial configuration via `UNREAL_CONFIG` injection token
|
|
372
|
-
- Auto-reconnection on WebRTC/DataChannel failures (configurable)
|
|
373
|
-
- File receiving from Unreal Engine via data channel
|
|
374
|
-
- Analytics and FPS monitoring
|
|
375
|
-
- Playwright testing mode with mock service substitution
|
|
376
|
-
|
|
377
|
-
## Examples
|
|
378
|
-
|
|
379
|
-
Check the demo application for complete usage examples:
|
|
380
|
-
|
|
381
|
-
```shell
|
|
382
|
-
pnpm demo:start
|
|
132
|
+
`UnrealSceneComponent` also accepts `isStudio`,
|
|
133
|
+
`useContainerAsSizeProvider` and `resolutionSize` inputs, and emits
|
|
134
|
+
`changeMouseOverScene`.
|
|
135
|
+
|
|
136
|
+
## Main API
|
|
137
|
+
|
|
138
|
+
- `provideUnrealState()` — registers the `unrealFeature` NgRx state.
|
|
139
|
+
- `provideUnrealModule()` — registers effects and boots streaming services.
|
|
140
|
+
- `UnrealSceneComponent` — renders and manages the Pixel Streaming scene.
|
|
141
|
+
- `UnrealCommunicatorService` — sends commands and UI interactions.
|
|
142
|
+
- `UnrealCallbackService` — observes Unreal callbacks and command responses.
|
|
143
|
+
- `unrealFeature`, exported selectors and actions — expose connection and scene
|
|
144
|
+
lifecycle state.
|
|
145
|
+
- `FileReceiverService` and `FileHandlerService` — receive files over the
|
|
146
|
+
DataChannel.
|
|
147
|
+
|
|
148
|
+
Command packet types are provided by `@3dsource/types-unreal`.
|
|
149
|
+
|
|
150
|
+
Run `pnpm demo:start` from the repository root to see the scene component in
|
|
151
|
+
the demo application.
|
|
152
|
+
|
|
153
|
+
## Optional prefetch scripts
|
|
154
|
+
|
|
155
|
+
The package publishes two dependency-free scripts for use in the document
|
|
156
|
+
`<head>` before Angular starts:
|
|
157
|
+
|
|
158
|
+
- `region-ping-prefetch.js` measures regions early and caches the closest one.
|
|
159
|
+
- `stream-prefetch.js` opens and parks an eligible WebRTC connection so Angular
|
|
160
|
+
can adopt it after bootstrap.
|
|
161
|
+
|
|
162
|
+
<!-- prettier-ignore -->
|
|
163
|
+
```html
|
|
164
|
+
<script
|
|
165
|
+
src="https://cdn.jsdelivr.net/npm/@3dsource/angular-unreal-module/js/region-ping-prefetch.js"
|
|
166
|
+
async
|
|
167
|
+
></script>
|
|
168
|
+
<script
|
|
169
|
+
src="https://cdn.jsdelivr.net/npm/@3dsource/angular-unreal-module/js/stream-prefetch.js"
|
|
170
|
+
async
|
|
171
|
+
></script>
|
|
383
172
|
```
|
|
384
173
|
|
|
385
|
-
|
|
174
|
+
`stream-prefetch.js` runs by default only on
|
|
175
|
+
`metabox-configurator/{modular|basic}/...` routes. It reads the same-origin
|
|
176
|
+
`assets/config.json`; override that path with `data-config-url` when needed.
|
|
177
|
+
Pin an exact package version in production when deterministic CDN assets are
|
|
178
|
+
required.
|
|
386
179
|
|
|
387
180
|
## Repository development
|
|
388
181
|
|
|
389
|
-
Run
|
|
182
|
+
Run commands from the repository root:
|
|
390
183
|
|
|
391
184
|
```shell
|
|
392
185
|
pnpm unreal:build
|
|
@@ -398,25 +191,22 @@ pnpm unreal:test:signalling
|
|
|
398
191
|
pnpm unreal:test:signalling:leaks
|
|
399
192
|
```
|
|
400
193
|
|
|
401
|
-
`unreal:build` builds `source-ui-native`, `types-unreal` and `utils`
|
|
402
|
-
|
|
403
|
-
watches `angular-unreal-module`.
|
|
194
|
+
`unreal:build` builds the local `source-ui-native`, `types-unreal` and `utils`
|
|
195
|
+
dependencies before this package.
|
|
404
196
|
|
|
405
|
-
|
|
197
|
+
Release commands publish only this package:
|
|
406
198
|
|
|
407
199
|
```shell
|
|
408
200
|
pnpm unreal:release:patch
|
|
409
201
|
pnpm unreal:release:dev
|
|
410
202
|
```
|
|
411
203
|
|
|
412
|
-
|
|
413
|
-
|
|
204
|
+
After a successful publish, the release automatically purges the matching
|
|
205
|
+
jsDelivr tag. Retry a failed purge without rerunning the release:
|
|
414
206
|
|
|
415
207
|
```shell
|
|
416
208
|
pnpm unreal:purge-cdn -- latest
|
|
209
|
+
pnpm unreal:purge-cdn -- dev
|
|
417
210
|
```
|
|
418
211
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
- Node.js: >=24.16.0
|
|
422
|
-
- pnpm: 11.17.0 (activated from the root `packageManager` field via Corepack)
|
|
212
|
+
Repository tooling requires Node.js 24.16.0 or newer and pnpm 11.17.0.
|