| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- 'use strict';
- // Anim Studio 导入器 —— Cocos Creator 3.8.x 编辑器扩展
- // 菜单:扩展 → Anim Studio → 1.导入 cocos-pack 资源 / 2.布置演示节点
- const fs = require('fs');
- const path = require('path');
- function projectAssets() {
- return path.join(Editor.Project.path, 'assets');
- }
- // 递归拷贝(Node 16+ 自带 fs.cpSync;做个兜底)
- function copyDir(src, dst) {
- if (fs.cpSync) { fs.cpSync(src, dst, { recursive: true }); return; }
- fs.mkdirSync(dst, { recursive: true });
- for (const name of fs.readdirSync(src)) {
- const s = path.join(src, name), d = path.join(dst, name);
- if (fs.statSync(s).isDirectory()) copyDir(s, d);
- else fs.copyFileSync(s, d);
- }
- }
- exports.methods = {
- // ---------- 1. 导入资源 ----------
- async importPack() {
- let picked;
- try {
- picked = await Editor.Dialog.select({
- title: '选择 Anim Studio 导出的 cocos-pack 文件夹',
- path: Editor.Project.path,
- type: 'directory',
- });
- } catch (e) {
- return Editor.Dialog.error('Anim Studio', { detail: '打开文件选择框失败:' + e });
- }
- if (!picked || picked.canceled || !picked.filePaths || !picked.filePaths.length) return;
- const pack = picked.filePaths[0];
- // 兼容:用户既可能选 cocos-pack 本身,也可能选到里面的 assets
- let srcAssets = path.join(pack, 'assets');
- if (!fs.existsSync(srcAssets) && fs.existsSync(path.join(pack, 'resources'))) {
- srcAssets = pack; // 选到了 assets 目录
- }
- if (!fs.existsSync(srcAssets)) {
- return Editor.Dialog.error('Anim Studio', {
- detail: '没找到 assets/(或 resources/)。请选 cocos-pack 文件夹,它里面应有 assets/resources 和 assets/scripts。',
- });
- }
- const dstAssets = projectAssets();
- const copied = [];
- try {
- for (const sub of ['resources', 'scripts']) {
- const s = path.join(srcAssets, sub);
- if (fs.existsSync(s)) { copyDir(s, path.join(dstAssets, sub)); copied.push(sub); }
- }
- } catch (e) {
- return Editor.Dialog.error('Anim Studio', { detail: '拷贝文件失败:' + e });
- }
- if (!copied.length) {
- return Editor.Dialog.error('Anim Studio', { detail: 'assets 里没有 resources / scripts 子目录。' });
- }
- // 让编辑器重新导入资源数据库
- try { await Editor.Message.request('asset-db', 'refresh-asset', 'db://assets'); } catch (e) {}
- Editor.Dialog.info('Anim Studio', {
- detail: '已导入:' + copied.join('、') +
- '。\n等右下角导入进度条走完后,新建或打开一个场景,再点菜单「2. 在当前场景布置演示节点」。',
- buttons: ['好的'],
- });
- },
- // ---------- 2. 布置演示节点 ----------
- async buildScene() {
- // 先确认有打开的场景
- let scene;
- try { scene = await Editor.Message.request('scene', 'query-is-ready'); } catch (e) {}
- try {
- // 找一个 Canvas 作父节点(新建 2D 场景默认就有,名为 Canvas)
- let parent = null;
- try {
- const tree = await Editor.Message.request('scene', 'query-node-tree');
- parent = findCanvasUuid(tree);
- } catch (e) {}
- const opt = { name: 'AnimStudioDemo' };
- if (parent) opt.parent = parent;
- const nodeUuid = await Editor.Message.request('scene', 'create-node', opt);
- const uuid = typeof nodeUuid === 'string' ? nodeUuid : (nodeUuid && nodeUuid.uuid);
- await Editor.Message.request('scene', 'create-component', { uuid, component: 'JellyDemo' });
- Editor.Dialog.info('Anim Studio', {
- detail: '已创建节点「AnimStudioDemo」并挂上 JellyDemo 组件。\n' +
- '按 Ctrl/Cmd+S 保存场景,再点上方 ▶ 播放即可。\n' +
- (parent ? '' : '(没检测到 Canvas,如果画面空白,请确认场景里有 Canvas,并把该节点拖到 Canvas 下。)'),
- buttons: ['完成'],
- });
- } catch (e) {
- Editor.Dialog.error('Anim Studio', {
- detail: '自动布置失败(多半是没有打开场景,或脚本还没导入完):' + e +
- '\n\n手动兜底:新建/打开一个场景 → 在 Canvas 下右键新建空节点 → 把 assets/scripts/JellyDemo.ts 拖到它的属性检查器上 → 保存并播放。',
- });
- }
- },
- };
- // 在节点树里找第一个名为 Canvas 的节点 uuid
- function findCanvasUuid(node) {
- if (!node) return null;
- if (Array.isArray(node)) {
- for (const n of node) { const r = findCanvasUuid(n); if (r) return r; }
- return null;
- }
- if (node.name === 'Canvas' && node.uuid) return node.uuid;
- if (node.children) return findCanvasUuid(node.children);
- return null;
- }
- exports.load = function () {};
- exports.unload = function () {};
|