1. 新增SkillView组件属性runType/endType/speed/time,替换原配置表字段 2. 批量同步所有技能prefab的配置参数 3. 优化技能运行逻辑,优先使用prefab配置,配置表仅作兜底 4. 新增同步脚本用于批量迁移技能配置
84 lines
3.2 KiB
JavaScript
84 lines
3.2 KiB
JavaScript
/**
|
||
* 一次性迁移脚本:把 SkillSet 中的 RType/EType/speed/time 刷入各技能 prefab 的 SkillView 序列化字段。
|
||
* 用法: node tools/sync-skill-prefab.js
|
||
* 注意: 直接改写 prefab JSON,运行前请保证工作区已提交。
|
||
*/
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const ROOT = path.resolve(__dirname, '..');
|
||
const SKILL_SET = path.join(ROOT, 'assets/script/game/common/config/SkillSet.ts');
|
||
const PREFAB_DIR = path.join(ROOT, 'assets/resources/game/skill/atk');
|
||
// SkillView 组件在 prefab 中的脚本类 cid
|
||
const SKILL_VIEW_CID = '57aabs7TE1J5obTAZczc+64';
|
||
|
||
const RTYPE = { linear: 0, bezier: 1, fixed: 2, fixedEnd: 3 };
|
||
const ETYPE = { animationEnd: 0, timeEnd: 1, collision: 2 };
|
||
|
||
/** 从 SkillSet.ts 解析 sp_name -> {runType, endType, speed, time} */
|
||
function parseSkillSet(src) {
|
||
const map = new Map();
|
||
// 匹配每个技能条目块
|
||
const entryRe = /\d+:\s*\{([\s\S]*?)\n\s*\},/g;
|
||
let m;
|
||
while ((m = entryRe.exec(src)) !== null) {
|
||
const body = m[1];
|
||
const sp = body.match(/sp_name:\s*"([^"]+)"/);
|
||
if (!sp) continue;
|
||
const spName = sp[1];
|
||
|
||
const rt = body.match(/RType:\s*RType\.(\w+)/);
|
||
const et = body.match(/EType:\s*EType\.(\w+)/);
|
||
const speed = body.match(/speed:\s*([\d.]+)/);
|
||
const time = body.match(/\btime:\s*([\d.]+)/);
|
||
|
||
const entry = {
|
||
runType: rt ? RTYPE[rt[1]] : undefined,
|
||
endType: et ? ETYPE[et[1]] : undefined,
|
||
speed: speed ? Number(speed[1]) : undefined,
|
||
time: time ? Number(time[1]) : 0,
|
||
};
|
||
// 多个技能可共用同一 sp_name,保留首个非 undefined 组合
|
||
if (!map.has(spName)) map.set(spName, entry);
|
||
}
|
||
return map;
|
||
}
|
||
|
||
function main() {
|
||
const src = fs.readFileSync(SKILL_SET, 'utf8');
|
||
const confMap = parseSkillSet(src);
|
||
|
||
const files = fs.readdirSync(PREFAB_DIR).filter(f => f.endsWith('.prefab'));
|
||
const report = { updated: [], skipped: [], noConf: [] };
|
||
|
||
for (const file of files) {
|
||
const spName = path.basename(file, '.prefab');
|
||
const conf = confMap.get(spName);
|
||
const fp = path.join(PREFAB_DIR, file);
|
||
const json = JSON.parse(fs.readFileSync(fp, 'utf8'));
|
||
|
||
// 定位 SkillView 组件
|
||
const comp = json.find(o => o && o.__type__ === SKILL_VIEW_CID);
|
||
if (!comp) { report.skipped.push(file + ' (no SkillView)'); continue; }
|
||
|
||
if (!conf) { report.noConf.push(file); continue; }
|
||
|
||
if (conf.runType !== undefined) comp.runType = conf.runType;
|
||
if (conf.endType !== undefined) comp.endType = conf.endType;
|
||
if (conf.speed !== undefined) comp.speed = conf.speed;
|
||
comp.time = conf.time ?? 0;
|
||
|
||
fs.writeFileSync(fp, JSON.stringify(json, null, 2) + '\n', 'utf8');
|
||
report.updated.push(`${file} -> runType=${comp.runType} endType=${comp.endType} speed=${comp.speed} time=${comp.time}`);
|
||
}
|
||
|
||
console.log('=== updated ===');
|
||
report.updated.forEach(s => console.log(' ' + s));
|
||
console.log('=== no config matched ===');
|
||
report.noConf.forEach(s => console.log(' ' + s));
|
||
console.log('=== skipped ===');
|
||
report.skipped.forEach(s => console.log(' ' + s));
|
||
}
|
||
|
||
main();
|