fix(particle): 修复粒子系统在浏览器预览中的资产加载和渲染 (#290)
* fix(editor): 修复粒子实体创建和优化检视器 - 添加 effects 分类到右键菜单,修复粒子实体无法创建的问题 - 添加粒子效果的本地化标签 - 简化粒子组件检视器,优先显示资产文件选择 - 高级属性只在未选择资产时显示,且默认折叠 - 添加可折叠的属性分组提升用户体验 * fix(particle): 修复粒子系统在浏览器预览中的资产加载和渲染 - 添加粒子 Gizmo 支持,显示发射形状并响应 Transform 缩放/旋转 - 修复资产热重载:添加 reloadAsset() 方法和 assets:refresh 事件监听 - 修复 VectorFieldEditors 数值输入精度(step 改为 0.01) - 修复浏览器预览中粒子资产加载失败的问题: - 将相对路径转换为绝对路径以正确复制资产文件 - 使用原始 GUID 而非生成的 GUID 构建 asset catalog - 初始化全局 assetManager 单例的 catalog 和 loader - 在 GameRuntime 的 systemContext 中添加 engineIntegration - 公开 AssetManager.initializeFromCatalog 方法供运行时使用
This commit is contained in:
@@ -35,6 +35,7 @@ import {
|
||||
import { ParticleEditorPanel } from './panels/ParticleEditorPanel';
|
||||
import { ParticleInspectorProvider } from './providers/ParticleInspectorProvider';
|
||||
import { useParticleEditorStore } from './stores/ParticleEditorStore';
|
||||
import { registerParticleGizmo, unregisterParticleGizmo } from './gizmos/ParticleGizmo';
|
||||
|
||||
// 导入编辑器 CSS 样式(会被 vite 自动处理并注入到 DOM)
|
||||
// Import editor CSS styles (automatically handled and injected by vite)
|
||||
@@ -45,6 +46,8 @@ import './styles/ParticleEditor.css';
|
||||
* Particle Editor Module
|
||||
*/
|
||||
export class ParticleEditorModule implements IEditorModuleLoader {
|
||||
private _assetsRefreshUnsubscribe: (() => void) | null = null;
|
||||
|
||||
async install(services: ServiceContainer): Promise<void> {
|
||||
// 注册检视器提供者 | Register inspector provider
|
||||
const inspectorRegistry = services.resolve(InspectorRegistry);
|
||||
@@ -72,10 +75,61 @@ export class ParticleEditorModule implements IEditorModuleLoader {
|
||||
createMessage: 'particle:create-asset'
|
||||
});
|
||||
}
|
||||
|
||||
// 注册 Gizmo | Register gizmo
|
||||
registerParticleGizmo();
|
||||
|
||||
// 监听资产刷新事件,当 .particle 文件保存时重新加载所有粒子组件
|
||||
// Listen for assets refresh event to reload particle components when .particle files are saved
|
||||
const messageHub = services.resolve(MessageHub);
|
||||
if (messageHub) {
|
||||
this._assetsRefreshUnsubscribe = messageHub.subscribe('assets:refresh', () => {
|
||||
this._reloadAllParticleAssets();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async uninstall(): Promise<void> {
|
||||
// 清理 | Clean up
|
||||
// 取消订阅事件 | Unsubscribe events
|
||||
if (this._assetsRefreshUnsubscribe) {
|
||||
this._assetsRefreshUnsubscribe();
|
||||
this._assetsRefreshUnsubscribe = null;
|
||||
}
|
||||
|
||||
// 取消注册 Gizmo | Unregister gizmo
|
||||
unregisterParticleGizmo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载所有粒子资产
|
||||
* Reload all particle assets
|
||||
*
|
||||
* 当资产文件变化时调用,强制所有粒子组件重新加载资产。
|
||||
* Called when asset files change, forcing all particle components to reload.
|
||||
*/
|
||||
private _reloadAllParticleAssets(): void {
|
||||
const scene = Core.scene;
|
||||
if (!scene) return;
|
||||
|
||||
// 遍历所有带有 ParticleSystemComponent 的实体
|
||||
// Iterate all entities with ParticleSystemComponent
|
||||
scene.entities.forEach((entity: Entity) => {
|
||||
const particle = entity.getComponent(ParticleSystemComponent) as ParticleSystemComponent | null;
|
||||
if (particle && particle.particleAssetGuid) {
|
||||
// 异步重新加载资产 | Async reload asset
|
||||
particle.reloadAsset().then((success: boolean) => {
|
||||
if (success) {
|
||||
console.log(`[ParticleEditorModule] Reloaded particle asset for entity: ${entity.name}`);
|
||||
// 标记需要重建并重新播放 | Mark dirty and replay
|
||||
particle.markDirty();
|
||||
if (particle.isPlaying) {
|
||||
particle.stop(true);
|
||||
particle.play();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getPanels(): PanelDescriptor[] {
|
||||
|
||||
Reference in New Issue
Block a user