Complete Cocos Creator port with level bundles, themes, and tooling.

Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-16 15:30:58 +08:00
parent cba5105908
commit d393302388
6248 changed files with 17322729 additions and 11036 deletions

View File

@@ -0,0 +1,58 @@
import { assetManager, JsonAsset } from 'cc';
import { PREVIEW } from 'cc/env';
/** assets/level-data/level-prefab-uuids.json烘焙脚本生成编辑器预览按 uuid 加载 prefab */
const EDITOR_UUID_INDEX = 'f7e8d9c0-b1a2-4c3d-9e8f-1a2b3c4d5e6f';
let uuidByLevelId: Record<number, string> | null = null;
let loadPromise: Promise<void> | null = null;
function ingest(data: Record<string, string>) {
const out: Record<number, string> = {};
for (const [k, v] of Object.entries(data ?? {})) {
const id = parseInt(k, 10);
const uuid = typeof v === 'string' ? v.trim() : '';
if (!Number.isNaN(id) && uuid) out[id] = uuid;
}
uuidByLevelId = out;
}
function loadFromEditorAsset(): Promise<void> {
return new Promise((resolve, reject) => {
assetManager.loadAny({ uuid: EDITOR_UUID_INDEX }, (err: Error | null, asset: JsonAsset) => {
if (err || !asset?.json) {
reject(err ?? new Error('level-prefab-uuids.json 未找到'));
return;
}
ingest(asset.json as Record<string, string>);
resolve();
});
});
}
/** 编辑器预览levelId → prefab uuid */
export function loadLevelPrefabUuidIndex(): Promise<void> {
if (uuidByLevelId) return Promise.resolve();
if (loadPromise) return loadPromise;
loadPromise = loadFromEditorAsset().catch((e) => {
console.warn('[LevelPrefabUuidIndex] 加载失败,将仅用 bundle 路径', e);
uuidByLevelId = {};
}).then(() => undefined);
return loadPromise;
}
export function getLevelPrefabUuid(levelId: number): string | undefined {
return uuidByLevelId?.[levelId];
}
/** level-prefabs/Level91601 → 91601 */
export function parseLevelIdFromPrefabPath(path: string): number | undefined {
const m = /Level(\d+)\s*$/.exec(path.trim());
if (!m) return undefined;
const id = parseInt(m[1], 10);
return Number.isNaN(id) ? undefined : id;
}
export function shouldTryEditorUuidLoad(): boolean {
return PREVIEW;
}