@3dsource/angular-unreal-module

中文文档
0.0.200发布于 2026/11/10UNLICENSEDTypeScriptES Module近 30 天下载 3102

非真实引擎像素流化的角集成

中文使用文档
文档目录11 节
  1. 所需资源
  2. 安装
  3. 入境点
  4. 样式
  5. 设置
  6. 1. 登记册状态和配置一次
  7. 2. 在懒惰的路线上启动引擎
  8. 3. 现场介绍
  9. 主要 API
  10. 可选预选脚本
  11. 仓库开发

@ 3d source/ angular- unreal- 模块

非真实引擎像素流化的独立角集成 。 包裹 提供场景组件,WebRTC和信号生命周期,NgRx状态, 命令/调回API、再连接、文件传输和遥测.

所需资源

  • 角、角 CDK 和角形式 >=19.0.0 <23.0.0
  • NgRx 存储和效果 >=19.0.0 <23.0.0
  • RxJS 软件 >=7.8.0 <8.0.0
  • @3dsource/types-unreal >=0.0.14 <0.1.0
  • provideHttpClient() 在主机应用程序中

安装

pnpm add @3dsource/angular-unreal-module @3dsource/types-unreal

软件包是独立的,不会暴露出一个NgModule.

入境点

入境点包含
@3dsource/angular-unreal-module一切——场景组件,服务,NgRx状态,提供者,助手
@3dsource/angular-unreal-module/configUNREAL_CONFIG, (中文(简体) ), UnrealInitialConfig, (中文(简体) ), UnrealMode 仅无发动机,266B型密克罗尼西亚

从 /config 在应用程序根中保留其他 在懒惰的路径后导入 设置 为什么.

样式

包装自有样式并不需要UI库. 画的一切 视频上方通过三个级别可以定制 这解决了你的案子.

需求职等费用
不同颜色/ 半径/ 字体设计符号3行CSS线
整个街区的外观类钩全球风格的一个类
内部的一组不同的元素插槽一个模板

三个级别组成: 符号再现留下的颜色, 级钩再现一个 块,一个插槽取代里面的东西。 插槽可以让班钩 同一部分无关紧要 里面的标记就全是你的了.

可以自定义的东西

这些是场景从录像上画出来的街区. 没有别的东西是他们的—— 视频本身, 和仅以德文为主的封面, 是超出范围.

块当用户看到时仅收件类钩子部件槽
装入状态连接时显示百分比✓statusCard, (中文(简体) ), statusMessageunrealStatusSlot
恢复/ 开始已暂停或尚未启动✓resumeCard, (中文(简体) ), resumeText, (中文(简体) ), resumeButtonunrealResumeSlot
AFK 超时下降前倒计时✓afkScrim, (中文(简体) ), afkCard, (中文(简体) ), afkButtonunrealAfkSlot

错误对话框( E)unreal-error-modal, (中文(简体) ), webrtc-error-modal已经 没有 部分内容 这个合同: 他们没有级钩,没有插槽, 他们读到 @3dsource/source-ui-native 指针( a)--src-*)而不是(a) --unreal-*他们 还在场外渲染出 DOM ——见"设计代号"下注.

1. 设计标志

设定 --unreal-* 变量在 app-unreal-scene ——自定义属性继承 穿过DOM,到达里面每个街区.

app-unreal-scene {
  --unreal-surface-card: #101014;
  --unreal-text-main: #f5f5f7;
  --unreal-radius-card: 16px;
}
脚本默认
--unreal-surface-card#fff
--unreal-surface-screen#fff
--unreal-surface-scrimrgba(100, 100, 100, .7)
--unreal-text-main#1f2937
--unreal-text-secondary#6b7280
--unreal-font-familysystem-ui, sans-serif
--unreal-radius-card8px
--unreal-radius-pill9999px
--unreal-shadow-card0 26px 80px 0 rgba(0,0,0,.2), 0 0 1px 0 rgba(0,0,0,.2)
--unreal-accent#017bff
--unreal-accent-hover#016fe6
--unreal-accent-text#fff

若为 @3dsource/source-ui-native 自动使用 在你没有设置的地方 --unreal-* 数值.

通过 CDK Dialog 打开的任何东西都无法达到 . 错误对话框 在现场DOM外的单独的上盖容器中渲染,所以变量 设置于 app-unreal-scene 永远无法到达他们 :root说明 这些对话框读取 --src-*没有 --unreal-*。 。 。 .

2. 级钩

自己提供一部分课程 替换 室内装饰课. 定位等级会留下来,因此场景布局无法被打破.

<app-unreal-scene [uiClasses]="{ resumeCard: 'my-card', statusCard: 'my-pill' }" />

部件 : resumeCard, (中文(简体) ), resumeText, (中文(简体) ), resumeButton, (中文(简体) ), afkScrim, (中文(简体) ), afkCard, (中文(简体) ), afkButton, (中文(简体) ), statusCard, (中文(简体) ), statusMessage。 。 。 .

你们的课必须用全球风格 (单位:千美元)styles.scss) (中文(简体) ). 已宣布为a 组件自己的SCSS,Angular瞄准它们,它们从未到达现场.

两个按钮部分的表现不同. resumeButton 财务报告和审定财务报表 afkButton 把你的课放在 <app-unreal-button> 主持人,但 <button> 内部是 图书馆部分,其风格有范围——和范围 .unreal-button 选择器( 0, 2, 0) 大于全局 .my-cta button (0, 1, 1) (中文(简体) ). 钩子是 对按钮有好处 外部 框中(宽、边距、对齐);修改 按钮本身,使用 --unreal-accent* 符号,或者一个槽,如果您想要 完全不同标记.

afkScrim 财务报告和审定财务报表 --unreal-surface-scrim 有一个提醒. 套装也 将留下一部分遗产, src/lib/styles/unreal.scss,则不属于 已公布的捆绑,且不准备导入。 它包含 .frame #videoPlayOverlay { background-color: … } - 一个id选择器 超过任何等级。 如果你导入了部分, 它胜过两个 类钩子和 AFK 覆盖背景的符号.

3. 槽数

将块的内容替换为您自己的标记 。 模块保存 包和能见度逻辑;通过模板上下文获取数据.

<app-unreal-scene>
  <ng-template unrealResumeSlot let-ctx>
    <button (click)="ctx.start()" class="my-cta">{{ ctx.isSecondStart() ? 'Resume' : 'Start' }}</button>
  </ng-template>

  <ng-template unrealStatusSlot let-ctx>
    <my-progress [value]="ctx.percents()" />
  </ng-template>
</app-unreal-scene>
指令A. 背景情况
unrealResumeSlotisSecondStart, (中文(简体) ), isAfkDisconnect, (中文(简体) ), start()
unrealAfkSlotcountdown (左边秒), reset()
unrealStatusSlotpercents, (中文(简体) ), message

除方法外,所有上下文值都是信号-在模板中调用. percents 实值 undefined 直到第一个值到达 —— 完成时守护它 它生动.

上下文对象被创建一次,从未被替换;什么是变化 里面有信号 这么说吧 let-ctx 是稳定的,你可以通过 ctx 在自由的周围.

插槽内的标记属于你,不是图书馆的. 角范围 a 模板到宣布该模板的组件,并宣布您的槽模板 内  组件。 有两个后果:

  • 图书馆的自有课 在那里什么都不做。 写入 class="resume-box__text" 在一个插槽内将无法取回模块的造型——该类的范围是: 模块.
  • 样式槽中包含您对任意标记的样式:您的组件 常设委员会通常适用(否) ::ng-deep,不需要全局样式表——与 阶级钩子.

这个 --unreal-* 符号 对 到达内部, 因为 CSS 自定义属性 通过 DOM 继承。 如果你想要你的标记也照做就读 主题:

.my-cta {
  background: var(--unreal-accent, #017bff);
  border-radius: var(--unreal-radius-card, 8px);
}

食谱

黑暗主题,没有别的. 一条规则, 无类型脚本 :

app-unreal-scene {
  --unreal-surface-card: #101014;
  --unreal-surface-screen: #0b0b0f;
  --unreal-text-main: #f5f5f7;
  --unreal-text-secondary: #a1a1aa;
  --unreal-shadow-card: 0 20px 60px 0 rgb(0 0 0 / 60%);
}

你的口音在按钮上. 扣子是用标志来重现的,不是 带有分级钩子——参见上注:

app-unreal-scene {
  --unreal-accent: #ff5f6d;
  --unreal-accent-hover: #f0454f;
  --unreal-accent-text: #fff;
}

如果您需要一个不同形状的按钮, 而不仅仅是重排, 替换 整个街区 unrealResumeSlot 并让自己的控制.

一个完全不同的装入状态. 结构,不仅仅是皮肤——所以 一个插槽。 可见度仍由模块决定:

<app-unreal-scene>
  <ng-template unrealStatusSlot let-ctx>
    <my-brand-progress [value]="ctx.percents() ?? 0" />
  </ng-template>
</app-unreal-scene>

你无法改变的东西

  • 当一个街区出现. 可见度留在模块上——条件 非三角( 连接状态、 重连接旗、 AFK 计时器) 和复制 在主机应用程序中它们是一个可靠的bug源.
  • 街上有个街区. 每个自定义元素都保留一个 一个主机级从未替换的定位类,所以场景布局不能 从外面断开。 移走这个街区 换来是重新安装容器.
  • 视频元素和 Dev 覆盖 (单位:千美元)video-stats, (中文(简体) ), stat-graph) (中文(简体) ).

设置

1. 登记册状态和配置一次

在应用程序中添加不真实特性状态、 HTTP 客户端和配置 树根. UNREAL_CONFIG 需要,尽管其所有领域都是可选的.

import { provideHttpClient } from '@angular/common/http';
import type { ApplicationConfig } from '@angular/core';
import { provideStore } from '@ngrx/store';
import { provideUnrealState } from '@3dsource/angular-unreal-module';
import {
  UNREAL_CONFIG,
  type UnrealInitialConfig,
} from '@3dsource/angular-unreal-module/config';

const unrealConfig = {
  regionsPingUrl: 'https://datacenter.3dsource.com/regions/',
  dataChannelConnectionTimeout: 8000,
  fpsMonitor: false,
} satisfies UnrealInitialConfig;

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(),
    provideStore(),
    provideUnrealState(),
    { provide: UNREAL_CONFIG, useValue: unrealConfig },
  ],
};

奥米 provideStore() 当 root NgRx 存储已配置时.

UNREAL_CONFIG 从 /config 有意进入 信物必须 可在 根号 注射器,因为模块的服务是 providedIn: 'root' 单通且无法看到路由级提供者。 包裹 自己作为密克罗尼西亚的船 建造在共同祖先的地块中放置一个模块 因此从包根中导入符使 整个引擎进入应用程序的急切捆绑。 在一个元盒生产建筑上 这是180 kB (49 kB gzip) 的原始 main 花在从未流出过的页面上.

这才有回报 没有别的了 在急切的图中导入软件包 树根。 遵循上述例子实际上没有资格—— provideUnrealState() 将密克罗尼西亚带回来。 一个想要的应用程序 引擎的初始捆绑动作 provideUnrealState() 对懒惰的人 路径并列 provideUnrealModule() (步骤2) UNREAL_CONFIG 供养于根.

可用的配置字段 :

外地目的
regionsPingUrl区域延迟终点
dataChannelConnectionTimeout数据频道连接超时( ms)
customErrorsEndpoint自定义错误报告终点
streamTelemetryV2Url流出生命周期遥测终点
screenLockerContainerId屏幕上挂的容器
mode'metabox' (default) – 完整的Metabox命令协议; 'default' —— sock Pixel Streaming app, 该模块不会发送自己的Metabox命令
fpsMonitor启用 FPS 监控( 目前关闭 —— 服务不即时)
disableFovRecalculation发送 payloadVersion: disableFovRecalculation 每一个分辨率变化,所以不真实保留相机FOV(工作室场景总是发送)
playwright启用测试特定服务行为

使用 { provide: UNREAL_CONFIG, useValue: {} } 用于最小配置.

2. 在懒惰的路线上启动引擎

从应用程序路由器上轻松地装入路由文件 :

import type { Routes } from '@angular/router';

export const APP_ROUTES: Routes = [
  {
    path: 'stream',
    loadChildren: () =>
      import('./stream/stream.routes').then((module) => module.STREAM_ROUTES),
  },
];

登记册 provideUnrealModule() 在懒惰路线文件中:

import type { Routes } from '@angular/router';
import { provideUnrealModule } from '@3dsource/angular-unreal-module';
import { StreamComponent } from './stream.component';

export const STREAM_ROUTES: Routes = [
  {
    path: '',
    component: StreamComponent,
    providers: [provideUnrealModule()],
  },
];

保留 provideUnrealState() 财务报告和审定财务报表 UNREAL_CONFIG 在应用程序根. 这个 loadChildren() 边界使流出引擎脱离初始 捆绑 路线界定 provideUnrealModule() 撕下它的效果 当 路线是左边的.

UNREAL_CONFIG 在路线上 providers 已经 没有 工作:引擎 服务是: providedIn: 'root',因此它们是由根注入器创建的 并读从那里得到的标志。 他们看不到路由级别值 inject(UNREAL_CONFIG, { optional: true }) 决定: null 例如 连接后区域从不运行(空) regionsPingUrl因此,没有 ưμ㼯a 没有一个。 只导入根上的符号不会将模块拖入 初始捆绑( 包是 sideEffects: false) (中文(简体) ).

3. 现场介绍

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { UnrealSceneComponent } from '@3dsource/angular-unreal-module';

@Component({
  selector: 'app-stream',
  imports: [UnrealSceneComponent],
  template: `<app-unreal-scene />`,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StreamComponent {}

UnrealSceneComponent 还接受 isStudio, (中文(简体) ), useContainerAsSizeProvider 财务报告和审定财务报表 resolutionSize 输入和输出 changeMouseOverScene。 。 。 .

主要 API

  • provideUnrealState() 登记 unrealFeature NGRx州.
  • provideUnrealModule() 登记效应和靴子流服务.
  • UnrealSceneComponent ——制作并管理像素流出场景.
  • UnrealCommunicatorService ——发送指令和UI交互.
  • UnrealCallbackService ——观察不真实的回调和命令响应.
  • unrealFeature,导出选择器和行动——显示连接和场景 生命周期状态.

命令包类型由 @3dsource/types-unreal。 。 。 .

那包装了两种轮廓 轮廓和QA 还有你的应用 此软件包必须解决 不变 一,选择是 tsconfig 路径在光谱上覆盖,从不导入。 一个无视的捆绑者 tsconfig 路径( 不匹配的平面维特或网络包) resolve.alias(中文(简体) ) 从一个轮廓取出类型,从另一个轮廓取出激发值,其中 运行时而非编译时失败 。 参见"两个轮廓:活出和QA" 输入 @3dsource/types-unreal 读取.

运行 pnpm demo:start 从寄存器根查看场景组件 演示应用程序.

可选预选脚本

软件包发布两个无依赖脚本,供文档使用 <head> 角开始前 :

  • region-ping-prefetch.js 提前测量区域,缓存全部结果 发布其活的答案。 连接从不等待: 请求 取了缓存区域, 否则预选者的答案, 如果它已经确定, 否则根本没有区域(由地理学IP来选择). 先装好 内 <head>;没有它,缓存会在第一次连接后被填充.
  • stream-prefetch.js 打开并停放一个符合条件的 WebRTC 连接, 这样 Angular 可以在靴子后通过.
<script
  src="https://cdn.jsdelivr.net/npm/@3dsource/angular-unreal-module/js/region-ping-prefetch.js"
  async
></script>
<script
  src="https://cdn.jsdelivr.net/npm/@3dsource/angular-unreal-module/js/stream-prefetch.js"
  async
></script>

stream-prefetch.js 只运行 metabox-configurator/modular/{configuratorId} 路由 — 配置符 id 来自于路由, 没有属性 : 提供一,因此无法为任意的页面启用脚本.

读作同源 assets/config.json 财务报告和审定财务报表 assets/features.json,则 配置器的缓存记录 {cdn}/cache/configurator/{id}.json - 那个 与主机应用程序读取的文件相同 使用而不是发明一个。 这个 newOrchestration 特性旗选择 运输: signalling (HTTP投票)或 newSignalling (控制接头+) requestStream) (中文(简体) ). 编剧: streamRequestId 已转发至 WebSocket URL 上的 Cirrus (会话) connectionId)并停放以供通过.

window.__stream 既是已停放的溪流, 又是锁: 任意一个脚本 和角模块首先写它拥有连接,所以一个页面永远不会 建设二. 从同一版本加载脚本和软件包——一个更古老的 脚本不知道锁.

可选 data-*数字 : data-config-url, (中文(简体) ), data-features-url, (中文(简体) ), data-ws-timeout, (中文(简体) ), data-poll-timeout。 。 。 .

当确定性CDN资产是时, 将精确的软件包版本刻入生产中 所需经费.

仓库开发

从寄存器根运行命令 :

pnpm unreal-module:build
pnpm unreal-module:build:watch
pnpm unreal-module:lint
pnpm unreal-module:test
pnpm unreal-module:test:watch
pnpm unreal-module:test:signalling
pnpm unreal-module:test:signalling:leaks

unreal-module:build 建立本地 types-unreal 在此软件包之前依赖 .

发布命令只发布此软件包 :

pnpm unreal-module:release:patch
pnpm unreal-module:release:dev

成功发布后, 发行会自动清除匹配 jsDelivr标签. 重试失败的清理而不重运行发行 :

pnpm unreal-module:purge-cdn -- latest
pnpm unreal-module:purge-cdn -- dev

Repository工具化需要Node.js 24.16.0或更新和pnpm上版本.

版本与发布记录

@3dsource/angular-unreal-module 共发布 270 个版本,首次发布于 2025/05/03;过去 12 个月发布了 193 个版本。

版本发布日期距今
0.0.200latest2026/11/10今天
0.0.200-dev.4dev2026/11/063 天前
0.0.200-dev.32026/11/064 天前
0.0.200-dev.22026/11/064 天前
0.0.200-dev.12026/11/064 天前
0.0.200-dev.02026/11/064 天前

关于 @3dsource/angular-unreal-module 的常见问题

@3dsource/angular-unreal-module 是什么?

非真实引擎像素流化的角集成

如何安装 @3dsource/angular-unreal-module?

在项目目录运行 npm install @3dsource/angular-unreal-module,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:rxjs(>=7.8.0 <8.0.0)、@ngrx/store(>=19.0.0 <23.0.0)、@angular/cdk(>=19.0.0 <23.0.0)、@angular/core(>=19.0.0 <23.0.0)、@ngrx/effects(>=19.0.0 <23.0.0)、@angular/common(>=19.0.0 <23.0.0)、@3dsource/types-unreal(>=0.0.14 <0.1.0)、@angular/platform-browser(>=19.0.0 <23.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@3dsource/angular-unreal-module 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@3dsource/angular-unreal-module 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@3dsource/angular-unreal-module 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@3dsource/angular-unreal-module 可以商用吗?

@3dsource/angular-unreal-module 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@3dsource/angular-unreal-module 的下载量有多少?

根据 npm 官方下载统计,@3dsource/angular-unreal-module 在 2026/10/05 – 2026/11/03 这 30 天内被下载 3,102 次,日均约 103 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@3dsource/angular-unreal-module 还在维护吗?

最新版本 0.0.200 发布于 2026/11/10(今天);至今共发布 270 个版本,其中过去 12 个月发布了 193 个;首次发布于 2025/05/03。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。