refactor(skill): 重构技能配置加载逻辑,将参数下沉至prefab配置
1. 新增SkillView组件属性runType/endType/speed/time,替换原配置表字段 2. 批量同步所有技能prefab的配置参数 3. 优化技能运行逻辑,优先使用prefab配置,配置表仅作兜底 4. 新增同步脚本用于批量迁移技能配置
This commit is contained in:
83
tools/sync-skill-prefab.js
Normal file
83
tools/sync-skill-prefab.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 一次性迁移脚本:把 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();
|
||||
Reference in New Issue
Block a user