Feature/physics and tilemap enhancement (#247)

* feat(behavior-tree,tilemap): 修复编辑器连线缩放问题并增强插件系统

* feat(node-editor,blueprint): 新增通用节点编辑器和蓝图可视化脚本系统

* feat(editor,tilemap): 优化编辑器UI样式和Tilemap编辑器功能

* fix: 修复CodeQL安全警告和CI类型检查错误

* fix: 修复CodeQL安全警告和CI类型检查错误

* fix: 修复CodeQL安全警告和CI类型检查错误
This commit is contained in:
YHH
2025-11-29 23:00:48 +08:00
committed by GitHub
parent f03b73b58e
commit 359886c72f
198 changed files with 33879 additions and 13121 deletions

View File

@@ -13,8 +13,10 @@ import type {
import {
EntityStoreService,
MessageHub,
ComponentRegistry
ComponentRegistry,
SettingsRegistry
} from '@esengine/editor-core';
import { DEFAULT_PHYSICS_CONFIG } from '../types/Physics2DTypes';
import { TransformComponent } from '@esengine/ecs-components';
// Local imports
@@ -24,15 +26,24 @@ import { CircleCollider2DComponent } from '../components/CircleCollider2DCompone
import { CapsuleCollider2DComponent } from '../components/CapsuleCollider2DComponent';
import { PolygonCollider2DComponent } from '../components/PolygonCollider2DComponent';
import { registerPhysics2DGizmos } from './gizmos/Physics2DGizmo';
import { Physics2DSystem } from '../systems/Physics2DSystem';
import { CollisionMatrixEditor } from './components/CollisionMatrixEditor';
/**
* Physics 2D Editor Module
* 2D 物理编辑器模块
*/
export class Physics2DEditorModule implements IEditorModuleLoader {
private settingsListener: ((event: Event) => void) | null = null;
async install(services: ServiceContainer): Promise<void> {
// 注册物理设置到设置面板
this.registerPhysicsSettings(services);
// 监听设置变更
this.setupSettingsListener();
// 注册组件到编辑器组件注册表
// 组件检视器现在通过 @Property 装饰器自动生成
const componentRegistry = services.resolve(ComponentRegistry);
if (componentRegistry) {
componentRegistry.register({
@@ -81,7 +92,193 @@ export class Physics2DEditorModule implements IEditorModuleLoader {
}
async uninstall(): Promise<void> {
// 清理资源
// 移除设置监听器
if (this.settingsListener) {
window.removeEventListener('settings:changed', this.settingsListener);
this.settingsListener = null;
}
}
/**
* 设置变更监听器
*/
private setupSettingsListener(): void {
this.settingsListener = ((event: CustomEvent) => {
const changedSettings = event.detail;
// 检查是否有物理相关设置变更
const physicsKeys = Object.keys(changedSettings).filter(k => k.startsWith('physics.'));
if (physicsKeys.length === 0) return;
this.applyPhysicsSettings(changedSettings);
}) as EventListener;
window.addEventListener('settings:changed', this.settingsListener);
}
/**
* 应用物理设置到物理系统
*/
private applyPhysicsSettings(settings: Record<string, unknown>): void {
const scene = Core.scene;
if (!scene) return;
const physicsSystem = scene.getSystem(Physics2DSystem);
if (!physicsSystem) return;
const world = physicsSystem.world;
if (!world) return;
// 构建配置对象
const gravityX = settings['physics.gravity.x'] as number | undefined;
const gravityY = settings['physics.gravity.y'] as number | undefined;
if (gravityX !== undefined || gravityY !== undefined) {
const currentGravity = world.getGravity();
world.updateConfig({
gravity: {
x: gravityX ?? currentGravity.x,
y: gravityY ?? currentGravity.y
}
});
}
if (settings['physics.timestep'] !== undefined) {
world.updateConfig({ timestep: settings['physics.timestep'] as number });
}
if (settings['physics.maxSubsteps'] !== undefined) {
world.updateConfig({ maxSubsteps: settings['physics.maxSubsteps'] as number });
}
if (settings['physics.velocityIterations'] !== undefined) {
world.updateConfig({ velocityIterations: settings['physics.velocityIterations'] as number });
}
if (settings['physics.positionIterations'] !== undefined) {
world.updateConfig({ positionIterations: settings['physics.positionIterations'] as number });
}
if (settings['physics.allowSleep'] !== undefined) {
world.updateConfig({ allowSleep: settings['physics.allowSleep'] as boolean });
}
}
/**
* 注册物理设置到设置面板
*/
private registerPhysicsSettings(services: ServiceContainer): void {
const settingsRegistry = services.tryResolve(SettingsRegistry);
if (!settingsRegistry) {
return;
}
settingsRegistry.registerCategory({
id: 'physics',
title: '物理',
description: '2D 物理引擎配置',
sections: [
{
id: 'physics-world',
title: '物理世界',
description: '配置物理世界的基础参数',
settings: [
{
key: 'physics.gravity.x',
label: '重力 X',
type: 'number',
defaultValue: DEFAULT_PHYSICS_CONFIG.gravity.x,
description: '水平方向重力(通常为 0',
step: 0.1
},
{
key: 'physics.gravity.y',
label: '重力 Y',
type: 'number',
defaultValue: DEFAULT_PHYSICS_CONFIG.gravity.y,
description: '垂直方向重力(负值向下)',
step: 0.1
},
{
key: 'physics.timestep',
label: '时间步长',
type: 'number',
defaultValue: DEFAULT_PHYSICS_CONFIG.timestep,
description: '固定物理更新时间步长(秒)',
min: 0.001,
max: 0.1,
step: 0.001
},
{
key: 'physics.maxSubsteps',
label: '最大子步数',
type: 'number',
defaultValue: DEFAULT_PHYSICS_CONFIG.maxSubsteps,
description: '每帧最大物理子步数',
min: 1,
max: 32,
step: 1
}
]
},
{
id: 'physics-solver',
title: '求解器',
description: '配置物理求解器参数',
settings: [
{
key: 'physics.velocityIterations',
label: '速度迭代次数',
type: 'number',
defaultValue: DEFAULT_PHYSICS_CONFIG.velocityIterations,
description: '速度求解器迭代次数,越高越精确但性能开销越大',
min: 1,
max: 16,
step: 1
},
{
key: 'physics.positionIterations',
label: '位置迭代次数',
type: 'number',
defaultValue: DEFAULT_PHYSICS_CONFIG.positionIterations,
description: '位置求解器迭代次数,越高越精确但性能开销越大',
min: 1,
max: 16,
step: 1
}
]
},
{
id: 'physics-behavior',
title: '行为',
description: '配置物理行为',
settings: [
{
key: 'physics.allowSleep',
label: '允许休眠',
type: 'boolean',
defaultValue: DEFAULT_PHYSICS_CONFIG.allowSleep,
description: '允许静止的刚体进入休眠状态以提高性能'
}
]
},
{
id: 'physics-collision',
title: '碰撞层',
description: '配置碰撞层和碰撞矩阵',
settings: [
{
key: 'physics.collisionMatrix',
label: '碰撞矩阵',
type: 'collisionMatrix',
defaultValue: null,
description: '配置哪些层之间可以发生碰撞',
customRenderer: CollisionMatrixEditor
}
]
}
]
});
}
getInspectorProviders() {