@3dsource/angular-unreal-module 0.0.44 → 0.0.46

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,16 +1,15 @@
1
1
  # @3dsource/angular-unreal-module
2
2
 
3
- A standalone Angular component for integrating Unreal Engine scenes into web applications. This module facilitates
4
- communication between Angular applications and Unreal Engine, enabling interactive 3D experiences.
3
+ A set of standalone Angular components, services, and providers for integrating Unreal Engine (WebRTC) scenes into Angular applications. It facilitates communication between Angular and Unreal Engine and enables interactive 3D experiences.
5
4
 
6
5
  ## Overview
7
6
 
8
- The Angular Unreal Module provides:
7
+ This package provides:
9
8
 
10
- - Seamless integration of Unreal Engine content in Angular applications
11
- - Communication bridge between Angular and Unreal Engine
12
- - State management for 3D scene interactions
13
- - Configurators for customizing Unreal Engine applications
9
+ - Standalone Unreal scene component to embed UE stream
10
+ - Communication bridge (commands, UI interactions, input data)
11
+ - NgRx state and effects for 3D stream lifecycle
12
+ - Config and utilities for telemetry, errors, and regions ping
14
13
 
15
14
  ## Installation
16
15
 
@@ -21,82 +20,139 @@ The Angular Unreal Module provides:
21
20
 
22
21
  ### Peer Dependencies
23
22
 
24
- This library requires the following peer dependencies:
23
+ This library requires the following peer dependencies (match or exceed versions):
25
24
 
26
25
  ```json
27
26
  {
28
- "@3dsource/source-ui-native": "^1.0.7",
29
- "@3dsource/types-unreal": "^0.0.1",
30
- "@3dsource/utils": "^1.0.13",
31
- "@angular/cdk": "^19.2.0",
32
- "@angular/common": "^19.2.0",
33
- "@angular/core": "^19.2.0",
34
- "@angular/forms": "^19.2.0",
35
- "@ngrx/effects": "^19.1.0",
36
- "@ngrx/operators": "^19.1.0",
37
- "@ngrx/store": "^19.1.0"
27
+ "@3dsource/source-ui-native": ">=1.0.9",
28
+ "@3dsource/types-unreal": ">=0.0.5",
29
+ "@3dsource/utils": ">=1.0.21",
30
+ "@angular/cdk": ">=19.0.0",
31
+ "@angular/common": ">=19.0.0",
32
+ "@angular/core": ">=19.0.0",
33
+ "@angular/forms": ">=19.0.0",
34
+ "@ngrx/effects": ">=19.0.0",
35
+ "@ngrx/store": ">=19.0.0"
38
36
  }
39
37
  ```
40
38
 
41
39
  ### Library Installation
42
40
 
43
41
  ```shell
44
- npm i @3dsource/angular-unreal-module
42
+ npm i @3dsource/angular-unreal-module
45
43
  ```
46
44
 
47
45
  ## Usage
48
46
 
49
- ### Basic Integration
50
-
51
- 1. Import the UnrealModule in your Angular application:
52
-
53
- ```typescript
54
- import { UnrealModule } from '@3dsource/angular-unreal-module';
55
-
56
- @NgModule({
57
- imports: [
58
- UnrealModule.forRoot({
59
- // Configuration options
60
- }),
47
+ The API is fully standalone (no NgModule). Use providers and components as shown below.
48
+
49
+ ### 1) Provide the module services and store slice
50
+
51
+ Add providers in your application bootstrap (e.g., app.config.ts):
52
+
53
+ ```ts
54
+ import { ApplicationConfig } from '@angular/core';
55
+ import { provideRouter } from '@angular/router';
56
+ import { provideStore } from '@ngrx/store';
57
+ import { provideEffects } from '@ngrx/effects';
58
+ import { provideAngularUnrealModule, UNREAL_CONFIG } from '@3dsource/angular-unreal-module';
59
+
60
+ export const appConfig: ApplicationConfig = {
61
+ providers: [
62
+ provideRouter([]),
63
+ // Root NgRx (if not already added in your app)
64
+ provideStore(),
65
+ provideEffects(),
66
+
67
+ // Unreal providers (adds feature state and effects internally)
68
+ ...provideAngularUnrealModule(),
69
+
70
+ // Optional initial config
71
+ { provide: UNREAL_CONFIG, useValue: {
72
+ // customErrorsEndpoint?: string,
73
+ // commandTelemetryReceiver?: string,
74
+ // regionsPingUrl?: string,
75
+ // screenLockerContainerId?: string,
76
+ // dataChannelConnectionTimeout?: number,
77
+ }
78
+ },
61
79
  ],
80
+ };
81
+ ```
82
+
83
+ ### 2) Use the Unreal scene component
84
+
85
+ Import the component into a standalone component and use it in the template.
86
+
87
+ ```ts
88
+ import { Component } from '@angular/core';
89
+ import { UnrealSceneComponent } from '@3dsource/angular-unreal-module';
90
+
91
+ @Component({
92
+ selector: 'app-root',
93
+ standalone: true,
94
+ imports: [UnrealSceneComponent],
95
+ template: `
96
+ <app-unreal-scene
97
+ [isStudio]="false"
98
+ [useContainerAsSizeProvider]="true"
99
+ [studioResolutionSize]="{ width: 1920, height: 1080 }"
100
+ (changeMouseOverScene)="onHover($event)"
101
+ ></app-unreal-scene>
102
+ `,
62
103
  })
63
- export class AppModule {}
104
+ export class AppComponent {
105
+ onHover(isOver: boolean) {
106
+ // handle mouse over scene
107
+ }
108
+ }
64
109
  ```
65
110
 
66
- 2. Use the Unreal scene component in your templates:
111
+ Component selector: <app-unreal-scene>
67
112
 
68
- ```html
69
- <unreal-scene [config]="unrealConfig" (sceneReady)="onSceneReady($event)"> </unreal-scene>
70
- ```
113
+ Inputs:
114
+ - isStudio: boolean = false
115
+ - useContainerAsSizeProvider: boolean = true
116
+ - studioResolutionSize: { width: number; height: number } = { width: 1920, height: 1080 }
71
117
 
72
- ### Communication with Unreal Engine
118
+ Outputs:
119
+ - changeMouseOverScene: EventEmitter<boolean>
73
120
 
74
- The module provides services for sending commands to and receiving events from Unreal Engine:
121
+ ### 3) Send commands / interactions to Unreal
75
122
 
76
- ```typescript
77
- import { UnrealService } from '@3dsource/angular-unreal-module';
123
+ Use UnrealCommunicatorService to send commands or UI interactions. Types for command packets are provided by @3dsource/types-unreal.
78
124
 
79
- @Component({ ... })
125
+ ```ts
126
+ import { Component, inject } from '@angular/core';
127
+ import { UnrealCommunicatorService } from '@3dsource/angular-unreal-module';
128
+ import type { MetaBoxCommandPacket } from '@3dsource/types-unreal';
129
+
130
+ @Component({ standalone: true, template: '' })
80
131
  export class MyComponent {
81
- constructor(private unrealService: UnrealService) {
82
- }
132
+ private unreal = inject(UnrealCommunicatorService);
83
133
 
84
- sendCommand() {
85
- this.unrealService.sendCommand({
134
+ sendSomeCommand() {
135
+ const packet: MetaBoxCommandPacket = {
86
136
  command: 'SomeCommand',
87
- parameters: { /* command parameters */ }
88
- });
137
+ parameters: { /* command parameters */ },
138
+ } as MetaBoxCommandPacket;
139
+
140
+ // Records telemetry and dispatches store events
141
+ this.unreal.sendCommandToUnreal(packet);
142
+ // Or use:
143
+ // this.unreal.emitCommand(packet); // to send as Command message
144
+ // this.unreal.emitUIInteraction(packet); // to send as UIInteraction
89
145
  }
90
146
  }
91
147
  ```
92
148
 
93
149
  ## Features
94
150
 
95
- - **Unreal Scene Component**: Embed Unreal Engine content in Angular applications
96
- - **Command API**: Send commands to Unreal Engine
97
- - **Event Handling**: React to events from Unreal Engine
98
- - **State Management**: NgRx integration for managing 3D scene state
99
- - **Configuration Options**: Customize the Unreal Engine integration
151
+ - Standalone Unreal Scene Component
152
+ - Command and UI Interaction API via UnrealCommunicatorService
153
+ - Event-driven status UI (freeze frame, video stats, play overlay)
154
+ - NgRx-powered state management and effects
155
+ - Optional initial configuration via UNREAL_CONFIG token
100
156
 
101
157
  ## Examples
102
158
 
@@ -3099,7 +3099,7 @@ class UnrealEffects {
3099
3099
  })));
3100
3100
  });
3101
3101
  this.forceLBMOff$ = createEffect(() => {
3102
- return fromEvent(document, 'visibilitychange').pipe(map(() => document.visibilityState === 'visible'), filter(Truthy), withLatestFrom(this.store.select(unrealFeature.selectLowBandwidth)), filter(([, isLowBandwidth]) => !!isLowBandwidth), tapLog('forceLBMOff$'), map(() => changeLowBandwidth({ lowBandwidth: false })));
3102
+ return fromEvent(document, 'visibilitychange').pipe(map(() => document.visibilityState === 'visible'), filter(Truthy), withLatestFrom(this.store.select(unrealFeature.selectLowBandwidth)), filter(([, isLowBandwidth]) => isLowBandwidth), tapLog('forceLBMOff$'), map(() => changeLowBandwidth({ lowBandwidth: false })));
3103
3103
  });
3104
3104
  this.resetFreezeFrameOnLowBandwidthTriggered$ = createEffect(() => {
3105
3105
  return this.actions$.pipe(ofType(changeLowBandwidth), map(({ lowBandwidth }) => lowBandwidth), distinctUntilChanged(), map(() => setFreezeFrame({ dataUrl: null, progress: null })));
@@ -3240,7 +3240,7 @@ const selectIsVideoPlayingAndDataChannelConnected = createSelector(unrealFeature
3240
3240
  const selectSignalingParameters = createSelector(unrealFeature.selectSsData, unrealFeature.selectAwsInstance, unrealFeature.selectSsInfo, (data, instance, ssInfo) => {
3241
3241
  const info = [];
3242
3242
  if (data) {
3243
- info.push(`${data.cirrusVersion}, ${data.branchInfo}`);
3243
+ info.push(`${data.cirrusVersion}, ${data.branchInfo}, ${data.instanceType}`);
3244
3244
  info.push(`Unreal App Version: ${data.streamerVersion}`);
3245
3245
  info.push(`APP: ${data.streamPath}${data.streamApp}`);
3246
3246
  }