diff --git a/assets/resources/game/skill/atk/a1.prefab b/assets/resources/game/skill/atk/a1.prefab index fa3b262f..22773e73 100644 --- a/assets/resources/game/skill/atk/a1.prefab +++ b/assets/resources/game/skill/atk/a1.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/a2.prefab b/assets/resources/game/skill/atk/a2.prefab index 13b078d4..6aace16a 100644 --- a/assets/resources/game/skill/atk/a2.prefab +++ b/assets/resources/game/skill/atk/a2.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/a3.prefab b/assets/resources/game/skill/atk/a3.prefab index ef8dcb76..73325895 100644 --- a/assets/resources/game/skill/atk/a3.prefab +++ b/assets/resources/game/skill/atk/a3.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/a4.prefab b/assets/resources/game/skill/atk/a4.prefab index 4f5238e6..239759d9 100644 --- a/assets/resources/game/skill/atk/a4.prefab +++ b/assets/resources/game/skill/atk/a4.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/a5.prefab b/assets/resources/game/skill/atk/a5.prefab index 0f3e05eb..ab9a6e9a 100644 --- a/assets/resources/game/skill/atk/a5.prefab +++ b/assets/resources/game/skill/atk/a5.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/atk.prefab b/assets/resources/game/skill/atk/atk.prefab index 8f5e345b..1911a6fd 100644 --- a/assets/resources/game/skill/atk/atk.prefab +++ b/assets/resources/game/skill/atk/atk.prefab @@ -108,8 +108,8 @@ }, "_lscale": { "__type__": "cc.Vec3", - "x": 1.6, - "y": 1.4, + "x": 1.3, + "y": 1.1, "z": 1 }, "_mobility": 0, @@ -252,7 +252,11 @@ "__id__": 11 }, "atk_x": 20, - "atk_y": 30, + "atk_y": 40, + "runType": 2, + "endType": 2, + "speed": 720, + "time": 0, "_id": "" }, { diff --git a/assets/resources/game/skill/atk/aw1.prefab b/assets/resources/game/skill/atk/aw1.prefab index a10d05b1..e02e6498 100644 --- a/assets/resources/game/skill/atk/aw1.prefab +++ b/assets/resources/game/skill/atk/aw1.prefab @@ -282,7 +282,11 @@ }, "atk_x": 10, "atk_y": 25, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -368,4 +372,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/aw2.prefab b/assets/resources/game/skill/atk/aw2.prefab index aa17581b..4e379a2f 100644 --- a/assets/resources/game/skill/atk/aw2.prefab +++ b/assets/resources/game/skill/atk/aw2.prefab @@ -282,7 +282,11 @@ }, "atk_x": 10, "atk_y": 25, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -368,4 +372,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/aw3.prefab b/assets/resources/game/skill/atk/aw3.prefab index ca90da60..0ad69b04 100644 --- a/assets/resources/game/skill/atk/aw3.prefab +++ b/assets/resources/game/skill/atk/aw3.prefab @@ -282,7 +282,11 @@ }, "atk_x": 10, "atk_y": 25, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -368,4 +372,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/b1.prefab b/assets/resources/game/skill/atk/b1.prefab index 251101ae..103a26df 100644 --- a/assets/resources/game/skill/atk/b1.prefab +++ b/assets/resources/game/skill/atk/b1.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/b2.prefab b/assets/resources/game/skill/atk/b2.prefab index fa278e94..35869421 100644 --- a/assets/resources/game/skill/atk/b2.prefab +++ b/assets/resources/game/skill/atk/b2.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/fb-1.prefab b/assets/resources/game/skill/atk/fb-1.prefab index 696cdbd9..fb68e589 100644 --- a/assets/resources/game/skill/atk/fb-1.prefab +++ b/assets/resources/game/skill/atk/fb-1.prefab @@ -253,7 +253,11 @@ }, "atk_x": 0, "atk_y": 0, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -368,4 +372,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/fb-2.prefab b/assets/resources/game/skill/atk/fb-2.prefab index ca66854f..a5c26b94 100644 --- a/assets/resources/game/skill/atk/fb-2.prefab +++ b/assets/resources/game/skill/atk/fb-2.prefab @@ -389,7 +389,11 @@ }, "atk_x": 0, "atk_y": 0, - "_id": "" + "_id": "", + "runType": 0, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -504,4 +508,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/h1.prefab b/assets/resources/game/skill/atk/h1.prefab index cb9d419c..2ce19644 100644 --- a/assets/resources/game/skill/atk/h1.prefab +++ b/assets/resources/game/skill/atk/h1.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/h2.prefab b/assets/resources/game/skill/atk/h2.prefab index c2981880..c89f85b6 100644 --- a/assets/resources/game/skill/atk/h2.prefab +++ b/assets/resources/game/skill/atk/h2.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/m1.prefab b/assets/resources/game/skill/atk/m1.prefab index b0396f82..a3e887c1 100644 --- a/assets/resources/game/skill/atk/m1.prefab +++ b/assets/resources/game/skill/atk/m1.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/resources/game/skill/atk/m2.prefab b/assets/resources/game/skill/atk/m2.prefab index aa086a73..83adc827 100644 --- a/assets/resources/game/skill/atk/m2.prefab +++ b/assets/resources/game/skill/atk/m2.prefab @@ -250,7 +250,11 @@ }, "atk_x": 10, "atk_y": 15, - "_id": "" + "_id": "", + "runType": 1, + "endType": 2, + "speed": 720, + "time": 0 }, { "__type__": "cc.CompPrefabInfo", @@ -336,4 +340,4 @@ "instance": null, "targetOverrides": null } -] \ No newline at end of file +] diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index 8c1bb54a..ae47c5b3 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -1,4 +1,4 @@ -// ========== 从 HeroAttrs.ts 导入属性相关定义 ========== +// ========== 从 HeroAttrs.ts 导入属性相关定义 ========== import { Attrs } from "./HeroAttrs"; export enum HSSet { @@ -134,6 +134,7 @@ export interface SkillConfig { gold?: number, // 获取金币技能的金币值 hit_count: number, // 可命中次数 hitcd: number, // 持续伤害的伤害间隔(秒) + /** @deprecated 已下沉到 SkillView @property(prefab 配置),此处仅作兜底 */ speed: number, // 移动速度 with: number, // 宽度(暂时无用) ready: number, // 前摇时间 @@ -142,11 +143,14 @@ export interface SkillConfig { EAnm: number, // 结束动画ID DAnm: string, // 命中后动画ID IType: IType, // 技能类型(近战/远程/辅助) + /** @deprecated 已下沉到 SkillView @property(prefab 配置),此处仅作兜底 */ RType: RType, // 技能运行类型(直线/贝塞尔/固定起点/固定终点) + /** @deprecated 已下沉到 SkillView @property(prefab 配置),此处仅作兜底 */ EType: EType, // 结束条件(动画结束/时间结束/距离结束/碰撞/次数结束) bezier_start_y?: number, // 贝塞尔起始抬升高度 bezier_mid_y?: number, // 贝塞尔中间高度增量 bezier_arc?: number, // 贝塞尔弧度系数 + /** @deprecated 已下沉到 SkillView @property(prefab 配置),此处仅作兜底 */ time?: number, // timeEnd 持续时间(秒) kind?: SkillKind, // 主效果类型 crt?: number, // 额外暴击率 diff --git a/assets/script/game/skill/SMoveSystem.ts b/assets/script/game/skill/SMoveSystem.ts index 57940137..2cfa510d 100644 --- a/assets/script/game/skill/SMoveSystem.ts +++ b/assets/script/game/skill/SMoveSystem.ts @@ -1,4 +1,4 @@ -import { v3, Vec3 ,Node} from "cc"; +import { v3, Vec3, Node } from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { EType, RType, SkillSet } from "../common/config/SkillSet"; import { SMoveDataComp } from "./SMoveComp"; @@ -26,46 +26,46 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate filter(): ecs.IMatcher { return ecs.allOf(SMoveDataComp, SkillView); } - + entityEnter(entity: ecs.Entity): void { const moveComp = entity.get(SMoveDataComp); const skillView = entity.get(SkillView); - + if (!moveComp || !skillView || !skillView.node) return; - + // 获取技能配置 const skillConfig = SkillSet[moveComp.s_uuid]; if (!skillConfig) { mLogger.warn(this.debugMode, 'SMoveSystem', `[SMoveSystem] 技能配置不存在: ${moveComp.s_uuid}`); return; } - - // 根据配置设置移动速度与加速度 - if (skillConfig.speed > 0) { + + // 移动参数由 prefab 的 SkillView @property 决定(speed<=0 时 Skill.load 已回退配置表值) + if (moveComp.speed <= 0) { moveComp.speed = skillConfig.speed; } if (skillConfig.is_accel) { moveComp.isAccelerate = true; } - + // 根据runType设置初始位置 this.initializePosition(moveComp, skillView); - + // 开始移动(除了固定位置类型) if (moveComp.runType !== RType.fixed && moveComp.runType !== RType.fixedEnd) { moveComp.startMove(); } - + mLogger.log(this.debugMode, 'SMoveSystem', `[SMoveSystem] 技能 ${skillConfig.name} 开始移动,类型: ${moveComp.runType}`); } - + /** * 根据runType初始化技能位置 */ private initializePosition(moveComp: SMoveDataComp, skillView: SkillView): void { const node = skillView.node; - - switch(moveComp.runType) { + + switch (moveComp.runType) { case RType.linear: // linear类型:根据atk_x和atk_y调整起始位置 const adjustedStartPos = v3( @@ -73,35 +73,35 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate moveComp.startPos.y + moveComp.atk_y, moveComp.startPos.z ); - + const originTargetPos = v3( moveComp.targetPos.x, moveComp.targetPos.y, moveComp.targetPos.z ); - + const direction = new Vec3(); Vec3.subtract(direction, originTargetPos, adjustedStartPos); - + // 延长终止点,统一消亡点的x坐标为 +-500 const targetX = moveComp.scale > 0 ? 500 : -500; let targetY = originTargetPos.y; - + if (Math.abs(direction.x) > 0.01) { const slope = direction.y / direction.x; targetY = adjustedStartPos.y + slope * (targetX - adjustedStartPos.x); } - + const adjustedTargetPos = v3( targetX, targetY, originTargetPos.z ); - + moveComp.startPos.set(adjustedStartPos); moveComp.targetPos.set(adjustedTargetPos); node.setPosition(adjustedStartPos); - + // 设置旋转角度 const dirForAngle = new Vec3(); Vec3.subtract(dirForAngle, adjustedTargetPos, adjustedStartPos); @@ -113,12 +113,12 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate node.angle = angle; } break; - + case RType.fixed: // 固定起始位置 node.setPosition(moveComp.startPos.x, node.position.y, 0); break; - + case RType.fixedEnd: // 固定结束位置 node.setPosition(moveComp.targetPos.x > 360 ? 300 : moveComp.targetPos.x, moveComp.targetPos.y, 0); @@ -154,26 +154,26 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate } update(entity: ecs.Entity): void { - if(!smc.mission.play ) return; - if(smc.mission.pause) return + if (!smc.mission.play) return; + if (smc.mission.pause) return const moveComp = entity.get(SMoveDataComp); const skillView = entity.get(SkillView); - + if (!moveComp || !skillView || !skillView.node) return; - + // 更新移动进度 const isMoving = moveComp.updateProgress(this.dt); - + if (isMoving) { // 更新节点位置 skillView.node.setPosition(moveComp.currentPos); - + // 处理自动旋转(贝塞尔移动) if (moveComp.runType === RType.bezier) { this.updateRotation(skillView.node, moveComp); } } - + // 检查移动完成 if (moveComp.isCompleted && moveComp.autoDestroy) { // 根据结束类型决定是否销毁 @@ -185,7 +185,7 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate } } } - + /** * 更新节点旋转(用于贝塞尔移动) */ @@ -193,29 +193,29 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate if (moveComp.progress < 1) { // 计算下一帧的位置来确定方向 const nextProgress = Math.min(moveComp.progress + 0.01, 1); - const t = moveComp.isAccelerate ? - (nextProgress * nextProgress * 0.7 + nextProgress * 0.3) : + const t = moveComp.isAccelerate ? + (nextProgress * nextProgress * 0.7 + nextProgress * 0.3) : nextProgress; const nextPos = v3(0, 0, 0); - + // 计算下一个位置 const oneMinusT = 1 - t; const oneMinusTSquared = oneMinusT * oneMinusT; const tSquared = t * t; const twoOneMinusTt = 2 * oneMinusT * t; - - nextPos.x = oneMinusTSquared * moveComp.startPos.x + - twoOneMinusTt * moveComp.controlPoint.x + - tSquared * moveComp.targetPos.x; - - nextPos.y = oneMinusTSquared * moveComp.startPos.y + - twoOneMinusTt * moveComp.controlPoint.y + - tSquared * moveComp.targetPos.y; - + + nextPos.x = oneMinusTSquared * moveComp.startPos.x + + twoOneMinusTt * moveComp.controlPoint.x + + tSquared * moveComp.targetPos.x; + + nextPos.y = oneMinusTSquared * moveComp.startPos.y + + twoOneMinusTt * moveComp.controlPoint.y + + tSquared * moveComp.targetPos.y; + // 计算方向角度 const direction = new Vec3(); Vec3.subtract(direction, nextPos, moveComp.currentPos); - + if (direction.length() > 0.01) { let angle = Math.atan2(direction.y, direction.x) * (180 / Math.PI); if (moveComp.scale < 0) { @@ -236,15 +236,15 @@ export class SMoveHelper { */ static setupMoveForSkill(entity: ecs.Entity, startPos: Vec3, targetPos: Vec3, s_uuid: number): void { let moveComp = entity.get(SMoveDataComp); - + if (!moveComp) { moveComp = entity.add(SMoveDataComp); } - + moveComp.startPos.set(startPos); moveComp.targetPos.set(targetPos); moveComp.s_uuid = s_uuid; - + // 从技能配置获取默认参数 const skillConfig = SkillSet[s_uuid]; if (skillConfig) { @@ -253,7 +253,7 @@ export class SMoveHelper { if (skillConfig.is_accel) moveComp.isAccelerate = true; } } - + /** * 检查技能是否正在移动 */ @@ -261,7 +261,7 @@ export class SMoveHelper { const moveComp = entity.get(SMoveDataComp); return moveComp ? moveComp.isMoving : false; } - + /** * 获取技能移动统计信息 */ @@ -269,7 +269,7 @@ export class SMoveHelper { const moveComp = entity.get(SMoveDataComp); return moveComp ? moveComp.getMoveStats() : null; } - + /** * 停止技能移动 */ diff --git a/assets/script/game/skill/Skill.ts b/assets/script/game/skill/Skill.ts index ec3fa1bc..08f3d9cb 100644 --- a/assets/script/game/skill/Skill.ts +++ b/assets/script/game/skill/Skill.ts @@ -146,7 +146,7 @@ export class Skill extends ecs.Entity { if (node.isValid) node.destroy(); return; } - if (config.EType != EType.collision) { + if (SView.endType != EType.collision) { const collider = node.getComponent(BoxCollider2D); if (collider) { collider.enabled = false @@ -174,8 +174,10 @@ export class Skill extends ecs.Entity { sMoveCom.targetPos.set(targetPos); sMoveCom.s_uuid = s_uuid; sMoveCom.scale = caster.node.scale.x < 0 ? -1 : 1; - sMoveCom.runType = config.RType; - sMoveCom.endType = config.EType; + // runType/endType/speed/time 由 prefab 的 SkillView @property 决定,配置表同名字段仅作兜底 + sMoveCom.runType = SView.runType; + sMoveCom.endType = SView.endType; + sMoveCom.speed = SView.speed > 0 ? SView.speed : config.speed; sMoveCom.bezierStartHeight = config.bezier_start_y ?? sMoveCom.bezierStartHeight; sMoveCom.bezierMidHeight = config.bezier_mid_y ?? sMoveCom.bezierMidHeight; sMoveCom.bezierArc = config.bezier_arc ?? sMoveCom.bezierArc; @@ -183,12 +185,12 @@ export class Skill extends ecs.Entity { sMoveCom.atk_x = SView.atk_x; sMoveCom.atk_y = SView.atk_y; - if (config.EType === EType.timeEnd) { + if (SView.endType === EType.timeEnd) { let sTimeCom = this.get(StimeDataComp); if (!sTimeCom) sTimeCom = this.add(StimeDataComp); sTimeCom.reset(); sTimeCom.s_uuid = s_uuid; - sTimeCom.totalTime = Math.max(1, config.time ?? 0); + sTimeCom.totalTime = Math.max(1, SView.time > 0 ? SView.time : (config.time ?? 0)); sTimeCom.hitInterval = Math.max(0.5, config.hitcd || 0); } else { const sTimeCom = this.get(StimeDataComp); diff --git a/assets/script/game/skill/SkillView.ts b/assets/script/game/skill/SkillView.ts index 2405fab2..cf7ebb4c 100644 --- a/assets/script/game/skill/SkillView.ts +++ b/assets/script/game/skill/SkillView.ts @@ -1,4 +1,4 @@ -import { _decorator, Animation, CCInteger, Collider2D, Contact2DType, UITransform, v3, Vec3 } from "cc"; +import { _decorator, Animation, CCFloat, CCInteger, Collider2D, Contact2DType, Enum, UITransform, v3, Vec3 } from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { HeroViewComp } from "../hero/HeroViewComp"; @@ -22,6 +22,22 @@ export class SkillView extends CCComp { @property({ type: CCInteger }) atk_y: number = 0 + /** 运动类型:直线/贝塞尔/固定起点/固定终点(由 prefab 配置,优先级高于 SkillSet) */ + @property({ type: Enum(RType), tooltip: "技能特效运动类型" }) + runType: RType = RType.linear; + + /** 消亡条件:动画结束/计时结束/碰撞次数结束(由 prefab 配置,优先级高于 SkillSet) */ + @property({ type: Enum(EType), tooltip: "技能特效消亡条件" }) + endType: EType = EType.collision; + + /** 移动速度(由 prefab 配置,<=0 时回退 SkillSet.speed) */ + @property({ type: CCFloat, slide: true, range: [0, 2000, 10], tooltip: "技能特效移动速度" }) + speed: number = 0; + + /** timeEnd 持续时间(秒),仅 endType=timeEnd 时生效(由 prefab 配置,<=0 时回退 SkillSet.time) */ + @property({ type: CCFloat, slide: true, range: [0, 30, 0.1], tooltip: "timeEnd 持续时间(秒)" }) + time: number = 0; + private debugMode: boolean = false; anim: Animation = null; @@ -45,7 +61,7 @@ export class SkillView extends CCComp { this.collider.group = this.group; this.collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); - this.collider.enabled = this.SConf?.EType === EType.collision; + this.collider.enabled = this.endType === EType.collision; } if (this.node.getComponent(Animation)) { let anim = this.node.getComponent(Animation); @@ -128,13 +144,13 @@ export class SkillView extends CCComp { onAnimationFinished() { // animationEnd 类型:动画结束后再关闭碰撞并销毁 - if (this.SConf.EType == EType.animationEnd) { + if (this.endType == EType.animationEnd) { this.disable_collider_now(); this.ent.destroy() return; } // fixed 类型不移动,无法通过移动完成销毁;动画播完作为兜底销毁时机 - if (this.SConf.RType == RType.fixed) { + if (this.runType == RType.fixed) { this.disable_collider_now(); this.ent.destroy() } @@ -142,7 +158,7 @@ export class SkillView extends CCComp { // 动画帧事件 atk:仅负责开启一帧碰撞窗口,不负责伤害与计数 public atk(args: any) { if (!this.SConf) return; - if (this.SConf.EType == EType.collision) return + if (this.endType == EType.collision) return if (this.enable_collider_safely()) { mLogger.log(this.debugMode, 'SkillView', `[SkillView] [${this.SConf?.name}] 开启碰撞检测`); this.scheduleOnce(() => { diff --git a/tools/sync-skill-prefab.js b/tools/sync-skill-prefab.js new file mode 100644 index 00000000..abbb6f88 --- /dev/null +++ b/tools/sync-skill-prefab.js @@ -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();