Feature/runtime cdn and plugin loader (#240)
* feat(ui): 完善 UI 布局系统和编辑器可视化工具 * refactor: 移除 ModuleRegistry,统一使用 PluginManager 插件系统 * fix: 修复 CodeQL 警告并提升测试覆盖率 * refactor: 分离运行时入口点,解决 runtime bundle 包含 React 的问题 * fix(ci): 添加 editor-core 和 editor-runtime 到 CI 依赖构建步骤 * docs: 完善 ServiceContainer 文档,新增 Symbol.for 模式和 @InjectProperty 说明 * fix(ci): 修复 type-check 失败问题 * fix(ci): 修复类型检查失败问题 * fix(ci): 修复类型检查失败问题 * fix(ci): behavior-tree 构建添加 @tauri-apps 外部依赖 * fix(ci): behavior-tree 添加 @tauri-apps/plugin-fs 类型依赖 * fix(ci): platform-web 添加缺失的 behavior-tree 依赖 * fix(lint): 移除正则表达式中不必要的转义字符
This commit is contained in:
@@ -36,7 +36,7 @@
|
||||
],
|
||||
"author": "ESEngine Team",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"peerDependencies": {
|
||||
"@esengine/ecs-framework": "workspace:*",
|
||||
"@esengine/ecs-components": "workspace:*",
|
||||
"@esengine/asset-system": "workspace:*"
|
||||
|
||||
@@ -275,6 +275,18 @@ export class EngineBridge implements IEngineBridge {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render sprites as overlay without clearing the screen.
|
||||
* 渲染精灵作为叠加层,不清除屏幕。
|
||||
*
|
||||
* This is used for UI rendering on top of world content.
|
||||
* 用于在世界内容上渲染 UI。
|
||||
*/
|
||||
renderOverlay(): void {
|
||||
if (!this.initialized) return;
|
||||
this.getEngine().renderOverlay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a texture.
|
||||
* 加载纹理。
|
||||
@@ -622,6 +634,109 @@ export class EngineBridge implements IEngineBridge {
|
||||
return this.getEngine().getViewportIds();
|
||||
}
|
||||
|
||||
// ===== Screen Space Mode API =====
|
||||
// ===== 屏幕空间模式 API =====
|
||||
|
||||
// Saved world space camera state
|
||||
// 保存的世界空间相机状态
|
||||
private savedWorldCamera: CameraConfig | null = null;
|
||||
|
||||
/**
|
||||
* Push screen space rendering mode.
|
||||
* 进入屏幕空间渲染模式。
|
||||
*
|
||||
* Saves the current world camera and switches to a fixed orthographic projection
|
||||
* centered at (0, 0) with the specified canvas size.
|
||||
* 保存当前世界相机并切换到以 (0, 0) 为中心的固定正交投影。
|
||||
*
|
||||
* @param canvasWidth - UI canvas width (design resolution) | UI 画布宽度(设计分辨率)
|
||||
* @param canvasHeight - UI canvas height (design resolution) | UI 画布高度(设计分辨率)
|
||||
*/
|
||||
pushScreenSpaceMode(canvasWidth: number, canvasHeight: number): void {
|
||||
if (!this.initialized) return;
|
||||
|
||||
// Save current world camera state
|
||||
// 保存当前世界相机状态
|
||||
this.savedWorldCamera = this.getCamera();
|
||||
|
||||
// Switch to screen space camera:
|
||||
// - Position at origin (0, 0)
|
||||
// - Zoom = 1 (1 pixel = 1 world unit)
|
||||
// - No rotation
|
||||
// 切换到屏幕空间相机:
|
||||
// - 位置在原点 (0, 0)
|
||||
// - 缩放 = 1(1 像素 = 1 世界单位)
|
||||
// - 无旋转
|
||||
//
|
||||
// For screen space UI, we want the camera to show exactly canvasWidth x canvasHeight pixels
|
||||
// centered at (0, 0). This means the visible area is:
|
||||
// X: [-canvasWidth/2, canvasWidth/2]
|
||||
// Y: [-canvasHeight/2, canvasHeight/2]
|
||||
// 对于屏幕空间 UI,我们希望相机精确显示 canvasWidth x canvasHeight 像素
|
||||
// 以 (0, 0) 为中心。这意味着可见区域是:
|
||||
// X: [-canvasWidth/2, canvasWidth/2]
|
||||
// Y: [-canvasHeight/2, canvasHeight/2]
|
||||
|
||||
// Get current viewport size to calculate proper zoom
|
||||
// 获取当前视口尺寸以计算正确的缩放
|
||||
// Note: This assumes canvas.width/height match actual rendering size
|
||||
// 注意:这假设 canvas.width/height 与实际渲染尺寸匹配
|
||||
const canvas = document.getElementById(this.config.canvasId) as HTMLCanvasElement;
|
||||
if (canvas) {
|
||||
// Calculate zoom so that canvasWidth x canvasHeight fits exactly in the viewport
|
||||
// 计算缩放使 canvasWidth x canvasHeight 正好适合视口
|
||||
// zoom = viewport_size / world_visible_size
|
||||
// For UI, we want 1 UI unit = 1 pixel on screen when canvas matches viewport
|
||||
// 对于 UI,当画布与视口匹配时,我们希望 1 UI 单位 = 1 屏幕像素
|
||||
const viewportWidth = canvas.width;
|
||||
const viewportHeight = canvas.height;
|
||||
|
||||
// Calculate zoom based on the design canvas size vs actual viewport
|
||||
// 根据设计画布尺寸与实际视口计算缩放
|
||||
// This scales UI to fit the viewport while maintaining aspect ratio
|
||||
const zoomX = viewportWidth / canvasWidth;
|
||||
const zoomY = viewportHeight / canvasHeight;
|
||||
|
||||
// Use minimum to ensure entire canvas is visible (letterbox if needed)
|
||||
// 使用最小值确保整个画布可见(如需要则显示黑边)
|
||||
const zoom = Math.min(zoomX, zoomY);
|
||||
|
||||
this.setCamera({
|
||||
x: 0,
|
||||
y: 0,
|
||||
zoom: zoom,
|
||||
rotation: 0
|
||||
});
|
||||
} else {
|
||||
// Fallback: use zoom = 1
|
||||
// 回退:使用 zoom = 1
|
||||
this.setCamera({
|
||||
x: 0,
|
||||
y: 0,
|
||||
zoom: 1,
|
||||
rotation: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop screen space rendering mode.
|
||||
* 退出屏幕空间渲染模式。
|
||||
*
|
||||
* Restores the previously saved world camera.
|
||||
* 恢复之前保存的世界相机。
|
||||
*/
|
||||
popScreenSpaceMode(): void {
|
||||
if (!this.initialized) return;
|
||||
|
||||
// Restore world camera
|
||||
// 恢复世界相机
|
||||
if (this.savedWorldCamera) {
|
||||
this.setCamera(this.savedWorldCamera);
|
||||
this.savedWorldCamera = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose the bridge and release resources.
|
||||
* 销毁桥接并释放资源。
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
export { EngineBridge, EngineBridgeConfig } from './core/EngineBridge';
|
||||
export { RenderBatcher } from './core/RenderBatcher';
|
||||
export { SpriteRenderHelper, ITransformComponent } from './core/SpriteRenderHelper';
|
||||
export { EngineRenderSystem, type TransformComponentType, type IRenderDataProvider, type GizmoDataProviderFn, type HasGizmoProviderFn } from './systems/EngineRenderSystem';
|
||||
export { EngineRenderSystem, type TransformComponentType, type IRenderDataProvider, type IUIRenderDataProvider, type GizmoDataProviderFn, type HasGizmoProviderFn, type ProviderRenderData } from './systems/EngineRenderSystem';
|
||||
export { CameraSystem } from './systems/CameraSystem';
|
||||
export * from './types';
|
||||
|
||||
@@ -34,6 +34,22 @@ export interface IRenderDataProvider {
|
||||
getRenderData(): readonly ProviderRenderData[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for UI render data providers
|
||||
* UI 渲染数据提供者接口
|
||||
*
|
||||
* All UI is rendered in Screen Space with independent orthographic projection.
|
||||
* 所有 UI 都在屏幕空间渲染,使用独立的正交投影。
|
||||
*/
|
||||
export interface IUIRenderDataProvider extends IRenderDataProvider {
|
||||
/** Get UI render data | 获取 UI 渲染数据 */
|
||||
getRenderData(): readonly ProviderRenderData[];
|
||||
/** @deprecated Use getRenderData() instead */
|
||||
getScreenSpaceRenderData?(): readonly ProviderRenderData[];
|
||||
/** @deprecated World space UI is no longer supported */
|
||||
getWorldSpaceRenderData?(): readonly ProviderRenderData[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal gizmo color interface (duck-typed, compatible with editor-core GizmoColor)
|
||||
* 内部 gizmo 颜色接口(鸭子类型,与 editor-core GizmoColor 兼容)
|
||||
@@ -145,6 +161,22 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
private gizmoDataProvider: GizmoDataProviderFn | null = null;
|
||||
private hasGizmoProvider: HasGizmoProviderFn | null = null;
|
||||
|
||||
// UI Canvas boundary settings
|
||||
// UI 画布边界设置
|
||||
private uiCanvasWidth: number = 0;
|
||||
private uiCanvasHeight: number = 0;
|
||||
private showUICanvasBoundary: boolean = true;
|
||||
|
||||
// UI render data provider (supports screen space and world space)
|
||||
// UI 渲染数据提供者(支持屏幕空间和世界空间)
|
||||
private uiRenderDataProvider: IUIRenderDataProvider | null = null;
|
||||
|
||||
// Preview mode flag: when true, UI uses screen space overlay projection
|
||||
// when false (editor mode), UI renders in world space following editor camera
|
||||
// 预览模式标志:为 true 时,UI 使用屏幕空间叠加投影
|
||||
// 为 false(编辑器模式)时,UI 在世界空间渲染,跟随编辑器相机
|
||||
private previewMode: boolean = false;
|
||||
|
||||
/**
|
||||
* Create a new engine render system.
|
||||
* 创建新的引擎渲染系统。
|
||||
@@ -190,6 +222,14 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
* Process all matched entities.
|
||||
* 处理所有匹配的实体。
|
||||
*
|
||||
* Rendering is done in two passes:
|
||||
* 1. World Pass: World sprites, tilemaps, gizmos (affected by world camera)
|
||||
* 2. UI Pass: Screen space UI (independent orthographic projection, overlaid on world)
|
||||
*
|
||||
* 渲染分两个阶段进行:
|
||||
* 1. 世界阶段:世界 Sprite、瓦片地图、Gizmo(受世界相机影响)
|
||||
* 2. UI 阶段:屏幕空间 UI(独立正交投影,叠加在世界之上)
|
||||
*
|
||||
* @param entities - Entities to process | 要处理的实体
|
||||
*/
|
||||
protected override process(entities: readonly Entity[]): void {
|
||||
@@ -197,6 +237,11 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
// 清空并重用映射用于绘制gizmo
|
||||
this.entityRenderMap.clear();
|
||||
|
||||
// ===== Pass 1: World Space Rendering =====
|
||||
// ===== 阶段 1:世界空间渲染 =====
|
||||
// This includes world sprites, tilemaps, and world space UI
|
||||
// 包括世界 Sprite、瓦片地图和世界空间 UI
|
||||
|
||||
// Collect all render items with sorting order
|
||||
// 收集所有渲染项及其排序顺序
|
||||
const renderItems: Array<{ sortingOrder: number; sprites: SpriteRenderData[] }> = [];
|
||||
@@ -259,7 +304,6 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
}
|
||||
|
||||
// Collect render data from providers (e.g., tilemap)
|
||||
// 收集来自提供者的渲染数据(如瓦片地图)
|
||||
for (const provider of this.renderDataProviders) {
|
||||
const renderDataList = provider.getRenderData();
|
||||
for (const data of renderDataList) {
|
||||
@@ -297,6 +341,18 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
}
|
||||
}
|
||||
|
||||
// Collect UI render data if in editor mode (renders in world space)
|
||||
// 如果在编辑器模式,收集 UI 渲染数据(在世界空间渲染)
|
||||
if (!this.previewMode && this.uiRenderDataProvider) {
|
||||
const uiRenderData = this.uiRenderDataProvider.getRenderData();
|
||||
for (const data of uiRenderData) {
|
||||
const uiSprites = this.convertProviderDataToSprites(data);
|
||||
if (uiSprites.length > 0) {
|
||||
renderItems.push({ sortingOrder: data.sortingOrder, sprites: uiSprites });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by sortingOrder (lower values render first, appear behind)
|
||||
// 按 sortingOrder 排序(值越小越先渲染,显示在后面)
|
||||
renderItems.sort((a, b) => a.sortingOrder - b.sortingOrder);
|
||||
@@ -332,7 +388,127 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
this.drawCameraFrustums();
|
||||
}
|
||||
|
||||
// Draw UI canvas boundary
|
||||
// 绘制 UI 画布边界
|
||||
if (this.showGizmos && this.showUICanvasBoundary && this.uiCanvasWidth > 0 && this.uiCanvasHeight > 0) {
|
||||
this.drawUICanvasBoundary();
|
||||
}
|
||||
|
||||
// ===== World Pass: Render world content =====
|
||||
// ===== 世界阶段:渲染世界内容 =====
|
||||
this.bridge.render();
|
||||
|
||||
// ===== Pass 2: Screen Space UI Rendering (Preview Mode Only) =====
|
||||
// ===== 阶段 2:屏幕空间 UI 渲染(仅预览模式)=====
|
||||
// UI is rendered on top of world content with independent projection
|
||||
// UI 使用独立投影渲染在世界内容之上
|
||||
// Only in preview mode - in editor mode, UI is rendered in world space above
|
||||
// 仅在预览模式 - 在编辑器模式,UI 在上面的世界空间渲染
|
||||
if (this.previewMode) {
|
||||
this.renderScreenSpaceUI();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render screen space UI with fixed orthographic projection.
|
||||
* 使用固定正交投影渲染屏幕空间 UI。
|
||||
*
|
||||
* Screen space UI is rendered with an independent orthographic projection
|
||||
* based on the UI canvas size, not affected by the world camera.
|
||||
* 屏幕空间 UI 使用基于 UI 画布尺寸的独立正交投影渲染,不受世界相机影响。
|
||||
*/
|
||||
private renderScreenSpaceUI(): void {
|
||||
if (!this.uiRenderDataProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all UI render data (now only screen space)
|
||||
// 获取所有 UI 渲染数据(现在只有屏幕空间)
|
||||
const uiRenderData = this.uiRenderDataProvider.getRenderData();
|
||||
if (uiRenderData.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Switch to screen space projection
|
||||
// 切换到屏幕空间投影
|
||||
// Use UI canvas size for the orthographic projection
|
||||
// 使用 UI 画布尺寸进行正交投影
|
||||
const canvasWidth = this.uiCanvasWidth > 0 ? this.uiCanvasWidth : 1920;
|
||||
const canvasHeight = this.uiCanvasHeight > 0 ? this.uiCanvasHeight : 1080;
|
||||
|
||||
// Save current camera state and switch to screen space mode
|
||||
// 保存当前相机状态并切换到屏幕空间模式
|
||||
this.bridge.pushScreenSpaceMode(canvasWidth, canvasHeight);
|
||||
|
||||
// Clear batcher for screen space content
|
||||
this.batcher.clear();
|
||||
|
||||
// Collect screen space UI render items
|
||||
const screenSpaceItems: Array<{ sortingOrder: number; sprites: SpriteRenderData[] }> = [];
|
||||
|
||||
for (const data of uiRenderData) {
|
||||
const uiSprites = this.convertProviderDataToSprites(data);
|
||||
if (uiSprites.length > 0) {
|
||||
screenSpaceItems.push({ sortingOrder: data.sortingOrder, sprites: uiSprites });
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by sortingOrder
|
||||
screenSpaceItems.sort((a, b) => a.sortingOrder - b.sortingOrder);
|
||||
|
||||
// Submit screen space UI sprites
|
||||
for (const item of screenSpaceItems) {
|
||||
for (const sprite of item.sprites) {
|
||||
this.batcher.addSprite(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.batcher.isEmpty) {
|
||||
const sprites = this.batcher.getSprites();
|
||||
this.bridge.submitSprites(sprites);
|
||||
// Render overlay (without clearing screen)
|
||||
// 渲染叠加层(不清屏)
|
||||
this.bridge.renderOverlay();
|
||||
}
|
||||
|
||||
// Restore world space camera
|
||||
// 恢复世界空间相机
|
||||
this.bridge.popScreenSpaceMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert provider render data to sprite render data array.
|
||||
* 将提供者渲染数据转换为 Sprite 渲染数据数组。
|
||||
*/
|
||||
private convertProviderDataToSprites(data: ProviderRenderData): SpriteRenderData[] {
|
||||
// Get texture ID - load from path if needed
|
||||
let textureId = data.textureIds[0] || 0;
|
||||
if (textureId === 0 && data.texturePath) {
|
||||
textureId = this.bridge.getOrLoadTextureByPath(data.texturePath);
|
||||
}
|
||||
|
||||
const sprites: SpriteRenderData[] = [];
|
||||
for (let i = 0; i < data.tileCount; i++) {
|
||||
const tOffset = i * 7;
|
||||
const uvOffset = i * 4;
|
||||
|
||||
const renderData: SpriteRenderData = {
|
||||
x: data.transforms[tOffset],
|
||||
y: data.transforms[tOffset + 1],
|
||||
rotation: data.transforms[tOffset + 2],
|
||||
scaleX: data.transforms[tOffset + 3],
|
||||
scaleY: data.transforms[tOffset + 4],
|
||||
originX: data.transforms[tOffset + 5],
|
||||
originY: data.transforms[tOffset + 6],
|
||||
textureId,
|
||||
uv: [data.uvs[uvOffset], data.uvs[uvOffset + 1], data.uvs[uvOffset + 2], data.uvs[uvOffset + 3]],
|
||||
color: data.colors[i]
|
||||
};
|
||||
|
||||
sprites.push(renderData);
|
||||
}
|
||||
|
||||
return sprites;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -675,6 +851,78 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw UI canvas boundary.
|
||||
* 绘制 UI 画布边界。
|
||||
*
|
||||
* Shows the design resolution boundary of the UI canvas.
|
||||
* 显示 UI 画布的设计分辨率边界。
|
||||
*/
|
||||
private drawUICanvasBoundary(): void {
|
||||
const w = this.uiCanvasWidth;
|
||||
const h = this.uiCanvasHeight;
|
||||
|
||||
// Canvas is centered at (0, 0) in Y-up coordinate system
|
||||
// 画布以 (0, 0) 为中心,Y 轴向上坐标系
|
||||
// Bottom-left: (-w/2, -h/2), Top-right: (w/2, h/2)
|
||||
|
||||
// Draw the boundary as a rectangle
|
||||
// 绘制边界矩形
|
||||
// Using origin (0, 0) means position is bottom-left corner
|
||||
// 使用 origin (0, 0) 表示位置是左下角
|
||||
this.bridge.addGizmoRect(
|
||||
-w / 2, // x: left edge
|
||||
-h / 2, // y: bottom edge (in Y-up system)
|
||||
w, // width
|
||||
h, // height
|
||||
0, // rotation
|
||||
0, // originX: left
|
||||
0, // originY: bottom
|
||||
0.5, 0.8, 1.0, 0.6, // Light blue color for UI canvas boundary
|
||||
false // Don't show transform handles
|
||||
);
|
||||
|
||||
// Draw corner markers for better visibility
|
||||
// 绘制角标记以提高可见性
|
||||
const markerSize = 20;
|
||||
const markerColor = { r: 0.5, g: 0.8, b: 1.0, a: 1.0 };
|
||||
|
||||
// Top-left corner marker (L shape)
|
||||
const corners = [
|
||||
// Top-left
|
||||
{ x: -w / 2, y: h / 2 - markerSize, ex: -w / 2, ey: h / 2 },
|
||||
{ x: -w / 2, y: h / 2, ex: -w / 2 + markerSize, ey: h / 2 },
|
||||
// Top-right
|
||||
{ x: w / 2 - markerSize, y: h / 2, ex: w / 2, ey: h / 2 },
|
||||
{ x: w / 2, y: h / 2, ex: w / 2, ey: h / 2 - markerSize },
|
||||
// Bottom-right
|
||||
{ x: w / 2, y: -h / 2 + markerSize, ex: w / 2, ey: -h / 2 },
|
||||
{ x: w / 2, y: -h / 2, ex: w / 2 - markerSize, ey: -h / 2 },
|
||||
// Bottom-left
|
||||
{ x: -w / 2 + markerSize, y: -h / 2, ex: -w / 2, ey: -h / 2 },
|
||||
{ x: -w / 2, y: -h / 2, ex: -w / 2, ey: -h / 2 + markerSize },
|
||||
];
|
||||
|
||||
for (const line of corners) {
|
||||
const dx = line.ex - line.x;
|
||||
const dy = line.ey - line.y;
|
||||
const length = Math.sqrt(dx * dx + dy * dy);
|
||||
const angle = Math.atan2(dy, dx);
|
||||
|
||||
this.bridge.addGizmoRect(
|
||||
(line.x + line.ex) / 2,
|
||||
(line.y + line.ey) / 2,
|
||||
length,
|
||||
2, // Line thickness
|
||||
angle,
|
||||
0.5,
|
||||
0.5,
|
||||
markerColor.r, markerColor.g, markerColor.b, markerColor.a,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set gizmo registry functions.
|
||||
* 设置 gizmo 注册表函数。
|
||||
@@ -711,6 +959,42 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
return this.showGizmos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set UI canvas size for boundary display.
|
||||
* 设置 UI 画布尺寸以显示边界。
|
||||
*
|
||||
* @param width - Canvas width (design resolution) | 画布宽度(设计分辨率)
|
||||
* @param height - Canvas height (design resolution) | 画布高度(设计分辨率)
|
||||
*/
|
||||
setUICanvasSize(width: number, height: number): void {
|
||||
this.uiCanvasWidth = width;
|
||||
this.uiCanvasHeight = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get UI canvas size.
|
||||
* 获取 UI 画布尺寸。
|
||||
*/
|
||||
getUICanvasSize(): { width: number; height: number } {
|
||||
return { width: this.uiCanvasWidth, height: this.uiCanvasHeight };
|
||||
}
|
||||
|
||||
/**
|
||||
* Set UI canvas boundary visibility.
|
||||
* 设置 UI 画布边界可见性。
|
||||
*/
|
||||
setShowUICanvasBoundary(show: boolean): void {
|
||||
this.showUICanvasBoundary = show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get UI canvas boundary visibility.
|
||||
* 获取 UI 画布边界可见性。
|
||||
*/
|
||||
getShowUICanvasBoundary(): boolean {
|
||||
return this.showUICanvasBoundary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set selected entity IDs.
|
||||
* 设置选中的实体ID。
|
||||
@@ -798,6 +1082,51 @@ export class EngineRenderSystem extends EntitySystem {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the UI render data provider.
|
||||
* 设置 UI 渲染数据提供者。
|
||||
*
|
||||
* The UI render data provider supports both screen space and world space UI.
|
||||
* UI 渲染数据提供者支持屏幕空间和世界空间 UI。
|
||||
*
|
||||
* @param provider - UI render data provider | UI 渲染数据提供者
|
||||
*/
|
||||
setUIRenderDataProvider(provider: IUIRenderDataProvider | null): void {
|
||||
this.uiRenderDataProvider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UI render data provider.
|
||||
* 获取 UI 渲染数据提供者。
|
||||
*/
|
||||
getUIRenderDataProvider(): IUIRenderDataProvider | null {
|
||||
return this.uiRenderDataProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set preview mode.
|
||||
* 设置预览模式。
|
||||
*
|
||||
* In preview mode (true): UI uses screen space overlay projection, independent of world camera.
|
||||
* In editor mode (false): UI renders in world space, following the editor camera.
|
||||
*
|
||||
* 预览模式(true):UI 使用屏幕空间叠加投影,独立于世界相机。
|
||||
* 编辑器模式(false):UI 在世界空间渲染,跟随编辑器相机。
|
||||
*
|
||||
* @param mode - True for preview mode, false for editor mode
|
||||
*/
|
||||
setPreviewMode(mode: boolean): void {
|
||||
this.previewMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preview mode.
|
||||
* 获取预览模式。
|
||||
*/
|
||||
isPreviewMode(): boolean {
|
||||
return this.previewMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of sprites rendered.
|
||||
* 获取渲染的精灵数量。
|
||||
|
||||
@@ -85,6 +85,14 @@ export class GameEngine {
|
||||
* * `show_handles` - Whether to show transform handles | 是否显示变换手柄
|
||||
*/
|
||||
addGizmoRect(x: number, y: number, width: number, height: number, rotation: number, origin_x: number, origin_y: number, r: number, g: number, b: number, a: number, show_handles: boolean): void;
|
||||
/**
|
||||
* Render sprites as overlay (without clearing screen).
|
||||
* 渲染精灵作为叠加层(不清除屏幕)。
|
||||
*
|
||||
* This is used for UI rendering on top of the world content.
|
||||
* 用于在世界内容上渲染 UI。
|
||||
*/
|
||||
renderOverlay(): void;
|
||||
/**
|
||||
* Resize a specific viewport.
|
||||
* 调整特定视口大小。
|
||||
@@ -259,6 +267,7 @@ export interface InitOutput {
|
||||
readonly gameengine_new: (a: number, b: number) => [number, number, number];
|
||||
readonly gameengine_registerViewport: (a: number, b: number, c: number, d: number, e: number) => [number, number];
|
||||
readonly gameengine_render: (a: number) => [number, number];
|
||||
readonly gameengine_renderOverlay: (a: number) => [number, number];
|
||||
readonly gameengine_renderToViewport: (a: number, b: number, c: number) => [number, number];
|
||||
readonly gameengine_resize: (a: number, b: number, c: number) => void;
|
||||
readonly gameengine_resizeViewport: (a: number, b: number, c: number, d: number, e: number) => void;
|
||||
|
||||
Reference in New Issue
Block a user