feat(asset): 统一资产引用使用 GUID 替代路径 (#287)

* feat(world-streaming): 添加世界流式加载系统

实现基于区块的世界流式加载系统,支持开放世界游戏:

运行时包 (@esengine/world-streaming):
- ChunkComponent: 区块实体组件,包含坐标、边界、状态
- StreamingAnchorComponent: 流式锚点组件(玩家/摄像机)
- ChunkLoaderComponent: 流式加载配置组件
- ChunkStreamingSystem: 区块加载/卸载调度系统
- ChunkCullingSystem: 区块可见性剔除系统
- ChunkManager: 区块生命周期管理服务
- SpatialHashGrid: 空间哈希网格
- ChunkSerializer: 区块序列化

编辑器包 (@esengine/world-streaming-editor):
- ChunkVisualizer: 区块可视化覆盖层
- ChunkLoaderInspectorProvider: 区块加载器检视器
- StreamingAnchorInspectorProvider: 流式锚点检视器
- WorldStreamingPlugin: 完整插件导出

* feat(asset): 统一资产引用使用 GUID 替代路径

将所有组件的资产引用字段从路径改为 GUID:
- SpriteComponent: texture -> textureGuid, material -> materialGuid
- SpriteAnimatorComponent: AnimationFrame.texture -> textureGuid
- UIRenderComponent: texture -> textureGuid
- UIButtonComponent: normalTexture -> normalTextureGuid 等
- AudioSourceComponent: clip -> clipGuid
- ParticleSystemComponent: 已使用 textureGuid

修复 AssetRegistryService 注册问题和路径规范化,
添加渲染系统的 GUID 解析支持。

* fix(sprite-editor): 更新 material 为 materialGuid

* fix(editor-app): 更新 AnimationFrame.texture 为 textureGuid
This commit is contained in:
YHH
2025-12-06 14:08:48 +08:00
committed by GitHub
parent 0c03b13d74
commit 3617f40309
25 changed files with 443 additions and 152 deletions

View File

@@ -109,9 +109,9 @@ export class SpriteRenderHelper {
// Convert hex color string to packed RGBA
const color = this.hexToPackedColor(sprite.color, sprite.alpha);
// Get material ID from path (0 = default if not found or no path specified)
const materialId = sprite.material
? getMaterialManager().getMaterialIdByPath(sprite.material)
// Get material ID from GUID (0 = default if not found or no GUID specified)
const materialId = sprite.materialGuid
? getMaterialManager().getMaterialIdByPath(sprite.materialGuid)
: 0;
// Collect material overrides if any

View File

@@ -10,6 +10,6 @@ export type { EngineBridgeConfig } from './core/EngineBridge';
export { RenderBatcher } from './core/RenderBatcher';
export { SpriteRenderHelper } from './core/SpriteRenderHelper';
export type { ITransformComponent } from './core/SpriteRenderHelper';
export { EngineRenderSystem, type TransformComponentType, type IRenderDataProvider, type IUIRenderDataProvider, type GizmoDataProviderFn, type HasGizmoProviderFn, type ProviderRenderData } from './systems/EngineRenderSystem';
export { EngineRenderSystem, type TransformComponentType, type IRenderDataProvider, type IUIRenderDataProvider, type GizmoDataProviderFn, type HasGizmoProviderFn, type ProviderRenderData, type AssetPathResolverFn } from './systems/EngineRenderSystem';
export { CameraSystem } from './systems/CameraSystem';
export * from './types';

View File

@@ -119,6 +119,18 @@ export type HasGizmoProviderFn = (component: Component) => boolean;
*/
export type TransformComponentType = ComponentType & (new (...args: any[]) => Component & ITransformComponent);
/**
* Asset path resolver function type.
* 资产路径解析器函数类型。
*
* Resolves GUID or path to actual file path for loading.
* 将 GUID 或路径解析为实际文件路径以进行加载。
*
* @param guidOrPath - Asset GUID or path | 资产 GUID 或路径
* @returns Resolved file path, or original value if cannot resolve | 解析后的文件路径,或无法解析时返回原值
*/
export type AssetPathResolverFn = (guidOrPath: string) => string;
/**
* ECS System for rendering sprites using the Rust engine.
* 使用Rust引擎渲染精灵的ECS系统。
@@ -177,6 +189,10 @@ export class EngineRenderSystem extends EntitySystem {
// UI 渲染数据提供者(支持屏幕空间和世界空间)
private uiRenderDataProvider: IUIRenderDataProvider | null = null;
// Asset path resolver (injected from editor layer for GUID resolution)
// 资产路径解析器(从编辑器层注入,用于 GUID 解析)
private assetPathResolver: AssetPathResolverFn | 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 使用屏幕空间叠加投影
@@ -288,14 +304,24 @@ export class EngineRenderSystem extends EntitySystem {
// Use Rust engine's path-based texture loading for automatic caching
// 使用Rust引擎的基于路径的纹理加载实现自动缓存
let textureId = 0;
if (sprite.texture) {
textureId = this.bridge.getOrLoadTextureByPath(sprite.texture);
const textureSource = sprite.getTextureSource();
if (textureSource) {
// Resolve GUID to path if resolver is available
// 如果有解析器,将 GUID 解析为路径
const texturePath = this.assetPathResolver
? this.assetPathResolver(textureSource)
: textureSource;
textureId = this.bridge.getOrLoadTextureByPath(texturePath);
}
// Get material ID from path (0 = default if not found or no path specified)
// 从路径获取材质 ID0 = 默认,如果未找到或未指定路径
const materialId = sprite.material
? getMaterialManager().getMaterialIdByPath(sprite.material)
// Get material ID from GUID (0 = default if not found or no GUID specified)
// 从 GUID 获取材质 ID0 = 默认,如果未找到或未指定 GUID
const materialGuidOrPath = sprite.materialGuid;
const materialPath = materialGuidOrPath && this.assetPathResolver
? this.assetPathResolver(materialGuidOrPath)
: materialGuidOrPath;
const materialId = materialPath
? getMaterialManager().getMaterialIdByPath(materialPath)
: 0;
// Collect material overrides if any
@@ -1159,4 +1185,28 @@ export class EngineRenderSystem extends EntitySystem {
loadTexture(id: number, url: string): void {
this.bridge.loadTexture(id, url);
}
/**
* Set asset path resolver.
* 设置资产路径解析器。
*
* The resolver function is used to convert asset GUIDs to file paths.
* This allows the editor to inject AssetRegistryService functionality
* without creating a direct dependency.
* 解析器函数用于将资产 GUID 转换为文件路径。
* 这允许编辑器注入 AssetRegistryService 功能而不创建直接依赖。
*
* @param resolver - Function to resolve GUID/path to actual path | 将 GUID/路径解析为实际路径的函数
*/
setAssetPathResolver(resolver: AssetPathResolverFn | null): void {
this.assetPathResolver = resolver;
}
/**
* Get asset path resolver.
* 获取资产路径解析器。
*/
getAssetPathResolver(): AssetPathResolverFn | null {
return this.assetPathResolver;
}
}