Files
esengine/packages/asset-system/src/interfaces/IPrefabAsset.ts
YHH beaa1d09de feat: 预制体系统与架构改进 (#303)
* feat(prefab): 实现预制体系统和编辑器 UX 改进

## 预制体系统
- 新增 PrefabSerializer: 预制体序列化/反序列化
- 新增 PrefabInstanceComponent: 追踪预制体实例来源和修改
- 新增 PrefabService: 预制体核心服务
- 新增 PrefabLoader: 预制体资产加载器
- 新增预制体命令: Create/Instantiate/Apply/Revert/BreakLink

## 预制体编辑模式
- 支持双击 .prefab 文件进入编辑模式
- 预制体编辑模式工具栏 (保存/退出)
- 预制体实例指示器和操作菜单

## 编辑器 UX 改进
- SceneHierarchy 快捷键: F2 重命名, Ctrl+D 复制, ↑↓ 导航
- 支持双击实体名称内联编辑
- 删除实体时显示子节点数量警告
- 右键菜单添加重命名/复制选项及快捷键提示
- 布局持久化和重置功能

## Bug 修复
- 修复 editor-runtime 组件类重复导致的 TransformComponent 不识别问题
- 修复 .prefab-name 样式覆盖导致预制体工具栏文字不可见
- 修复 Inspector 资源字段高度不正确问题

* feat(editor): 改进编辑器 UX 交互体验

- ContentBrowser: 加载动画 spinner、搜索高亮、改进空状态设计
- SceneHierarchy: 选中项自动滚动到视图、搜索清除按钮
- PropertyInspector: 输入框本地状态管理、Enter/Escape 键处理
- EntityInspector: 组件折叠状态持久化、属性搜索清除按钮
- Viewport: 变换操作实时数值显示
- 国际化: 添加相关文本 (en/zh)

* fix(build): 修复 Web 构建资产加载和编辑器 UX 改进

构建系统修复:
- 修复 asset-catalog.json 字段名不匹配 (entries vs assets)
- 修复 BrowserFileSystemService 支持两种目录格式
- 修复 bundle 策略检测逻辑 (空对象判断)
- 修复 module.json 中 assetExtensions 声明和类型推断

行为树修复:
- 修复 BehaviorTreeExecutionSystem 使用 loadAsset 替代 loadAssetByPath
- 修复 BehaviorTreeAssetType 常量与 module.json 类型名一致 (behavior-tree)

编辑器 UX 改进:
- 构建完成对话框添加"打开文件夹"按钮
- 构建完成对话框样式优化 (圆形图标背景、按钮布局)
- SceneHierarchy 响应式布局 (窄窗口自动隐藏 Type 列)
- SceneHierarchy 隐藏滚动条

错误追踪:
- 添加全局错误处理器写入日志文件 (%TEMP%/esengine-editor-crash.log)
- 添加 append_to_log Tauri 命令

* feat(render): 修复 UI 渲染和点击特效系统

## UI 渲染修复
- 修复 GUID 验证 bug,使用统一的 isValidGUID() 函数
- 修复 UI 渲染顺序随机问题,Rust 端使用 IndexMap 替代 HashMap
- Web 运行时添加 assetPathResolver 支持 GUID 解析
- UIInteractableComponent.blockEvents 默认值改为 false

## 点击特效系统
- 新增 ClickFxComponent 和 ClickFxSystem
- 支持在点击位置播放粒子效果
- 支持多种触发模式和粒子轮换

## Camera 系统重构
- CameraSystem 从 ecs-engine-bindgen 移至 camera 包
- 新增 CameraManager 统一管理相机

## 编辑器改进
- 改进属性面板 UI 交互
- 粒子编辑器面板优化
- Transform 命令系统

* feat(render): 实现 Sorting Layer 系统和 Overlay 渲染层

- 新增 SortingLayerManager 管理排序层级 (Background, Default, Foreground, UI, Overlay)
- 实现 ISortable 接口,统一 Sprite、UI、Particle 的排序属性
- 修复粒子 Overlay 层被 UI 遮挡问题:添加独立的 Overlay Pass 在 UI 之后渲染
- 更新粒子资产格式:从 sortingOrder 改为 sortingLayer + orderInLayer
- 更新粒子编辑器面板支持新的排序属性
- 优化 UI 渲染系统使用新的排序层级

* feat(ci): 集成 SignPath 代码签名服务

- 添加 SignPath 自动签名工作流(Windows)
- 配置 release-editor.yml 支持代码签名
- 将构建改为草稿模式,等待签名完成后发布
- 添加证书文件到 .gitignore 防止泄露

* fix(asset): 修复 Web 构建资产路径解析和全局单例移除

## 资产路径修复
- 修复 Tauri 本地服务器 `/asset?path=...` 路径解析,正确与 root 目录连接
- BrowserPathResolver 支持两种模式:
  - 'proxy': 使用 /asset?path=... 格式(编辑器 Run in Browser)
  - 'direct': 使用直接路径 /assets/path.png(独立 Web 构建)
- BrowserRuntime 使用 'direct' 模式,无需 Tauri 代理

## 架构改进 - 移除全局单例
- 移除 globalAssetManager 导出,改用 AssetManagerToken 依赖注入
- 移除 globalPathResolver 导出,改用 PathResolutionService
- 移除 globalPathResolutionService 导出
- ParticleUpdateSystem/ClickFxSystem 通过 setAssetManager() 注入依赖
- EngineService 使用 new AssetManager() 替代全局实例

## 新增服务
- PathResolutionService: 统一路径解析接口
- RuntimeModeService: 运行时模式查询服务
- SerializationContext: EntityRef 序列化上下文

## 其他改进
- 完善 ServiceToken 注释说明本地定义的意图
- 导出 BrowserPathResolveMode 类型

* fix(build): 添加 world-streaming composite 设置修复类型检查

* fix(build): 移除 world-streaming 引用避免 composite 冲突

* fix(build): 将 const enum 改为 enum 兼容 isolatedModules

* fix(build): 添加缺失的 IAssetManager 导入
2025-12-13 19:44:08 +08:00

406 lines
9.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 预制体资产接口定义
* Prefab asset interface definitions
*
* 定义预制体系统的核心类型,包括预制体数据格式、元数据、实例化选项等。
* Defines core types for the prefab system including data format, metadata, instantiation options, etc.
*/
import type { AssetGUID } from '../types/AssetTypes';
import type { SerializedEntity } from '@esengine/ecs-framework';
/**
* 预制体序列化实体(扩展自 SerializedEntity
* Serialized prefab entity (extends SerializedEntity)
*
* 在标准 SerializedEntity 基础上添加预制体特定属性。
* Adds prefab-specific properties on top of standard SerializedEntity.
*/
export interface SerializedPrefabEntity extends SerializedEntity {
/**
* 是否为预制体根节点
* Whether this is the prefab root entity
*/
isPrefabRoot?: boolean;
/**
* 嵌套预制体的 GUID如果此实体是另一个预制体的实例
* GUID of nested prefab (if this entity is an instance of another prefab)
*/
nestedPrefabGuid?: AssetGUID;
}
/**
* 预制体元数据
* Prefab metadata
*/
export interface IPrefabMetadata {
/**
* 预制体名称
* Prefab name
*/
name: string;
/**
* 资产 GUID在保存为资产后填充
* Asset GUID (populated after saving as asset)
*/
guid?: AssetGUID;
/**
* 创建时间戳
* Creation timestamp
*/
createdAt: number;
/**
* 最后修改时间戳
* Last modification timestamp
*/
modifiedAt: number;
/**
* 使用的组件类型列表
* List of component types used
*/
componentTypes: string[];
/**
* 引用的资产 GUID 列表
* List of referenced asset GUIDs
*/
referencedAssets: AssetGUID[];
/**
* 预制体描述
* Prefab description
*/
description?: string;
/**
* 预制体标签(用于分类和搜索)
* Prefab tags (for categorization and search)
*/
tags?: string[];
/**
* 缩略图数据Base64 编码)
* Thumbnail data (Base64 encoded)
*/
thumbnail?: string;
}
/**
* 组件类型注册条目
* Component type registry entry
*/
export interface IPrefabComponentTypeEntry {
/**
* 组件类型名称
* Component type name
*/
typeName: string;
/**
* 组件版本号
* Component version number
*/
version: number;
}
/**
* 预制体文件数据格式
* Prefab file data format
*
* 这是 .prefab 文件的完整结构。
* This is the complete structure of a .prefab file.
*/
export interface IPrefabData {
/**
* 预制体格式版本号
* Prefab format version number
*/
version: number;
/**
* 预制体元数据
* Prefab metadata
*/
metadata: IPrefabMetadata;
/**
* 根实体数据(包含完整的实体层级)
* Root entity data (contains full entity hierarchy)
*/
root: SerializedPrefabEntity;
/**
* 组件类型注册表(用于版本管理和兼容性检查)
* Component type registry (for versioning and compatibility checks)
*/
componentTypeRegistry: IPrefabComponentTypeEntry[];
}
/**
* 预制体资产(加载后的内存表示)
* Prefab asset (in-memory representation after loading)
*/
export interface IPrefabAsset {
/**
* 预制体数据
* Prefab data
*/
data: IPrefabData;
/**
* 资产 GUID
* Asset GUID
*/
guid: AssetGUID;
/**
* 资产路径
* Asset path
*/
path: string;
/**
* 根实体数据(快捷访问)
* Root entity data (quick access)
*/
readonly root: SerializedPrefabEntity;
/**
* 包含的组件类型列表(快捷访问)
* List of component types used (quick access)
*/
readonly componentTypes: string[];
/**
* 引用的资产列表(快捷访问)
* List of referenced assets (quick access)
*/
readonly referencedAssets: AssetGUID[];
}
/**
* 预制体实例化选项
* Prefab instantiation options
*/
export interface IPrefabInstantiateOptions {
/**
* 父实体 ID可选
* Parent entity ID (optional)
*/
parentId?: number;
/**
* 位置覆盖
* Position override
*/
position?: { x: number; y: number };
/**
* 旋转覆盖(角度)
* Rotation override (in degrees)
*/
rotation?: number;
/**
* 缩放覆盖
* Scale override
*/
scale?: { x: number; y: number };
/**
* 实体名称覆盖
* Entity name override
*/
name?: string;
/**
* 是否保留原始实体 ID默认 false生成新 ID
* Whether to preserve original entity IDs (default false, generate new IDs)
*/
preserveIds?: boolean;
/**
* 是否标记为预制体实例(默认 true
* Whether to mark as prefab instance (default true)
*/
trackInstance?: boolean;
/**
* 属性覆盖(组件属性覆盖)
* Property overrides (component property overrides)
*/
propertyOverrides?: IPrefabPropertyOverride[];
}
/**
* 预制体属性覆盖
* Prefab property override
*
* 用于记录预制体实例对原始预制体属性的修改。
* Used to record modifications to prefab properties in instances.
*/
export interface IPrefabPropertyOverride {
/**
* 目标实体路径(从根节点的相对路径,如 "Root/Child/GrandChild"
* Target entity path (relative path from root, e.g., "Root/Child/GrandChild")
*/
entityPath: string;
/**
* 组件类型名称
* Component type name
*/
componentType: string;
/**
* 属性路径(支持嵌套,如 "position.x"
* Property path (supports nesting, e.g., "position.x")
*/
propertyPath: string;
/**
* 覆盖值
* Override value
*/
value: unknown;
}
/**
* 预制体创建选项
* Prefab creation options
*/
export interface IPrefabCreateOptions {
/**
* 预制体名称
* Prefab name
*/
name: string;
/**
* 预制体描述
* Prefab description
*/
description?: string;
/**
* 预制体标签
* Prefab tags
*/
tags?: string[];
/**
* 是否包含子实体
* Whether to include child entities
*/
includeChildren?: boolean;
/**
* 保存路径(可选,用于指定保存位置)
* Save path (optional, for specifying save location)
*/
savePath?: string;
}
/**
* 预制体服务接口
* Prefab service interface
*
* 提供预制体的创建、实例化、管理等功能。
* Provides prefab creation, instantiation, management, etc.
*/
export interface IPrefabService {
/**
* 从实体创建预制体数据
* Create prefab data from entity
*
* @param entity - 源实体 | Source entity
* @param options - 创建选项 | Creation options
* @returns 预制体数据 | Prefab data
*/
createPrefab(entity: unknown, options: IPrefabCreateOptions): IPrefabData;
/**
* 实例化预制体
* Instantiate prefab
*
* @param prefab - 预制体资产 | Prefab asset
* @param scene - 目标场景 | Target scene
* @param options - 实例化选项 | Instantiation options
* @returns 创建的根实体 | Created root entity
*/
instantiate(prefab: IPrefabAsset, scene: unknown, options?: IPrefabInstantiateOptions): unknown;
/**
* 通过 GUID 实例化预制体
* Instantiate prefab by GUID
*
* @param guid - 预制体资产 GUID | Prefab asset GUID
* @param scene - 目标场景 | Target scene
* @param options - 实例化选项 | Instantiation options
* @returns 创建的根实体 | Created root entity
*/
instantiateByGuid(guid: AssetGUID, scene: unknown, options?: IPrefabInstantiateOptions): Promise<unknown>;
/**
* 检查实体是否为预制体实例
* Check if entity is a prefab instance
*
* @param entity - 要检查的实体 | Entity to check
* @returns 是否为预制体实例 | Whether it's a prefab instance
*/
isPrefabInstance(entity: unknown): boolean;
/**
* 获取预制体实例的源预制体 GUID
* Get source prefab GUID of a prefab instance
*
* @param entity - 预制体实例 | Prefab instance
* @returns 源预制体 GUID如果不是实例则返回 null | Source prefab GUID, null if not an instance
*/
getSourcePrefabGuid(entity: unknown): AssetGUID | null;
/**
* 将实例的修改应用到源预制体
* Apply instance modifications to source prefab
*
* @param instance - 预制体实例 | Prefab instance
* @returns 是否成功应用 | Whether application was successful
*/
applyToPrefab?(instance: unknown): Promise<boolean>;
/**
* 将实例还原为源预制体的状态
* Revert instance to source prefab state
*
* @param instance - 预制体实例 | Prefab instance
* @returns 是否成功还原 | Whether revert was successful
*/
revertToPrefab?(instance: unknown): Promise<boolean>;
/**
* 获取实例相对于源预制体的属性覆盖
* Get property overrides of instance relative to source prefab
*
* @param instance - 预制体实例 | Prefab instance
* @returns 属性覆盖列表 | List of property overrides
*/
getPropertyOverrides?(instance: unknown): IPrefabPropertyOverride[];
}
/**
* 预制体文件格式版本
* Prefab file format version
*/
export const PREFAB_FORMAT_VERSION = 1;
/**
* 预制体文件扩展名
* Prefab file extension
*/
export const PREFAB_FILE_EXTENSION = '.prefab';