From 5bd2e15fb5f0b87a311b4fe5dba8e976a479bd89 Mon Sep 17 00:00:00 2001 From: panw Date: Mon, 3 Nov 2025 10:57:08 +0800 Subject: [PATCH] =?UTF-8?q?refactor(skill):=20=E4=BC=98=E5=8C=96=E6=8A=80?= =?UTF-8?q?=E8=83=BD=E7=A2=B0=E6=92=9E=E6=A3=80=E6=B5=8B=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=B9=B6=E7=A7=BB=E9=99=A4=E9=87=8D=E5=A4=8D=E5=91=BD=E4=B8=AD?= =?UTF-8?q?=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除hitTargets集合及相关重复命中检查逻辑 - 改进碰撞检测日志输出,增加安全性检查 - 清理注释掉的旧攻击逻辑代码 - 在reset方法中添加碰撞器事件解绑 --- assets/resources/game/heros/mo3.prefab | 2 +- assets/resources/game/heros/mo4.prefab | 4 +- assets/resources/game/skill/atk/atk_s1.prefab | 2 +- .../game/skill/atk/b_arrow_blue.prefab | 2 +- .../game/skill/atk/m_water_ball_1.prefab | 4 +- assets/script/game/skill/SkillView.ts | 161 +++++++++--------- 6 files changed, 89 insertions(+), 86 deletions(-) diff --git a/assets/resources/game/heros/mo3.prefab b/assets/resources/game/heros/mo3.prefab index 862b5bf5..5930ffc1 100644 --- a/assets/resources/game/heros/mo3.prefab +++ b/assets/resources/game/heros/mo3.prefab @@ -996,7 +996,7 @@ "__id__": 62 }, "tag": 0, - "_group": 4, + "_group": 2, "_density": 1, "_sensor": true, "_friction": 0.2, diff --git a/assets/resources/game/heros/mo4.prefab b/assets/resources/game/heros/mo4.prefab index 61384aff..849d8af8 100644 --- a/assets/resources/game/heros/mo4.prefab +++ b/assets/resources/game/heros/mo4.prefab @@ -996,9 +996,9 @@ "__id__": 62 }, "tag": 0, - "_group": 4, + "_group": 2, "_density": 1, - "_sensor": true, + "_sensor": false, "_friction": 0.2, "_restitution": 0, "_offset": { diff --git a/assets/resources/game/skill/atk/atk_s1.prefab b/assets/resources/game/skill/atk/atk_s1.prefab index ebd959ef..96133980 100644 --- a/assets/resources/game/skill/atk/atk_s1.prefab +++ b/assets/resources/game/skill/atk/atk_s1.prefab @@ -301,7 +301,7 @@ "bullet": false, "awakeOnLoad": true, "_group": 1, - "_type": 2, + "_type": 1, "_allowSleep": false, "_gravityScale": 1, "_linearDamping": 0, diff --git a/assets/resources/game/skill/atk/b_arrow_blue.prefab b/assets/resources/game/skill/atk/b_arrow_blue.prefab index 229854bf..a6850817 100644 --- a/assets/resources/game/skill/atk/b_arrow_blue.prefab +++ b/assets/resources/game/skill/atk/b_arrow_blue.prefab @@ -513,7 +513,7 @@ "tag": 0, "_group": 1, "_density": 1, - "_sensor": true, + "_sensor": false, "_friction": 0.2, "_restitution": 0, "_offset": { diff --git a/assets/resources/game/skill/atk/m_water_ball_1.prefab b/assets/resources/game/skill/atk/m_water_ball_1.prefab index 9cc17b69..c6786560 100644 --- a/assets/resources/game/skill/atk/m_water_ball_1.prefab +++ b/assets/resources/game/skill/atk/m_water_ball_1.prefab @@ -304,8 +304,8 @@ "bullet": false, "awakeOnLoad": true, "_group": 1, - "_type": 2, - "_allowSleep": true, + "_type": 1, + "_allowSleep": false, "_gravityScale": 1, "_linearDamping": 0, "_angularDamping": 0, diff --git a/assets/script/game/skill/SkillView.ts b/assets/script/game/skill/SkillView.ts index 2875d349..f89233ca 100644 --- a/assets/script/game/skill/SkillView.ts +++ b/assets/script/game/skill/SkillView.ts @@ -30,7 +30,6 @@ export class SkillView extends CCComp { sData:SDataCom=null; s_uuid:number=1001 // 已命中目标追踪,防止重复伤害 - private hitTargets: Set = new Set(); start() { this.SConf = SkillSet[this.s_uuid] this.sData=this.ent.get(SDataCom) @@ -49,24 +48,28 @@ export class SkillView extends CCComp { } onBeginContact (seCol: Collider2D, oCol: Collider2D) { - const targetId = oCol.uuid; - if(this.hitTargets.has(targetId)) return; // 已经命中过,跳过 - // 记录命中目标 - - // if (!this.SConf) return; - // if(this.SConf.EType!=EType.collision) return - if(oCol.group == seCol.group) return - let target = oCol.getComponent(HeroViewComp) - if(target == null) return; - let model=target.ent.get(HeroAttrsComp) - console.log(`[skillView] 碰撞3`,oCol.group,seCol.group,model); - if(model == null) return - if(model.is_dead) return - if(this.sData.fac == model.fac) return; - // 检查是否已经命中过这个目标 - console.log(`[skillView] 碰撞5[${this.sData.caster.box_group}][${this.sData.caster.ent.get(HeroAttrsComp).hero_name}][${this.sData.caster.ent.eid}]的[${this.group}] [${this.SConf.name}]碰撞了 [${oCol.group}][ ${oCol.getComponent(HeroViewComp).ent.get(HeroAttrsComp).hero_name}][${oCol.getComponent(HeroViewComp).ent.eid}]`); - this.hitTargets.add(targetId); - this.apply_damage(target) + // 安全获取双方信息用于日志 + const casterName = this.sData.caster?.ent?.get(HeroAttrsComp)?.hero_name ?? '未知施法者'; + const casterEid = this.sData.caster?.ent?.eid ?? '未知EID'; + const targetView = oCol.getComponent(HeroViewComp); + const targetName = targetView?.ent?.get(HeroAttrsComp)?.hero_name ?? '非英雄对象'; + const targetEid = targetView?.ent?.eid ?? '未知EID'; + console.log(`[skillView] 碰撞1 [${this.sData.caster.box_group}][${casterName}][${casterEid}]的[${seCol.group}]:[${this.SConf.name}][${this.ent.eid}]碰撞了 [${oCol.group}]:[ ${targetName}][${targetEid}]`); + // 基本空值与同组过滤 + if (!this.sData || !this.SConf) { + console.warn('[SkillView] onBeginContact 缺少 sData 或 SConf,忽略此次碰撞'); + return; + } + if (oCol.group === seCol.group) return; + // 不是 HeroViewComp,直接忽略 + if (!targetView) return; + let model = targetView.ent.get(HeroAttrsComp); + // console.log(`[skillView] 碰撞3`, oCol.group, seCol.group, model); + if (!model) return; + if (model.is_dead) return; + if (this.sData.fac == model.fac) return; + // 检查是否已经命中过这个目标(日志安全输出) + this.apply_damage(targetView) } onAnimationFinished(){ @@ -74,70 +77,59 @@ export class SkillView extends CCComp { this.ent.destroy() } } - //动画帧事件 atk 触发 - public atk(args:any){ - let dis=this.node.getComponent(UITransform).width/2 - let enemys:any=[] - if( this.sData.fac==FacSet.HERO){ - enemys=ecs.query(ecs.allOf(MonMoveComp)) - }else{ - enemys=ecs.query(ecs.allOf(HeroMoveComp)) - } - let IRTargets: HeroViewComp[] = [] - // 收集范围内所有敌方目标 - enemys.some(e => { - const view = e.get(HeroViewComp); - const model=e.get(HeroAttrsComp) - const distance = Math.abs(this.node.position.x - view.node.position.x); - if(distance <= dis&&!model.is_dead) { - IRTargets.push(view); - } + // //动画帧事件 atk 触发 + // public atk(args:any){ + // let dis=this.node.getComponent(UITransform).width/2 + // let enemys:any=[] + // if( this.sData.fac==FacSet.HERO){ + // enemys=ecs.query(ecs.allOf(MonMoveComp)) + // }else{ + // enemys=ecs.query(ecs.allOf(HeroMoveComp)) + // } + // let IRTargets: HeroViewComp[] = [] + // // 收集范围内所有敌方目标 + // enemys.some(e => { + // const view = e.get(HeroViewComp); + // const model=e.get(HeroAttrsComp) + // const distance = Math.abs(this.node.position.x - view.node.position.x); + // if(distance <= dis&&!model.is_dead) { + // IRTargets.push(view); + // } - }); - // 根据配置的hit_num决定攻击模式 - const hitNum = SkillSet[this.s_uuid].hit_num || 0; - if(hitNum > 0) { - // 限制目标数量:按距离排序,选择最近的N个目标 - if(IRTargets.length > 0) { - // 按距离排序(从近到远) - IRTargets.sort((a, b) => { - const distanceA = Math.abs(this.node.position.x - a.node.position.x); - const distanceB = Math.abs(this.node.position.x - b.node.position.x); - return distanceA - distanceB; - }); - // 限制目标数量 - const maxTargets = Math.min(hitNum, IRTargets.length); - const sTargets = IRTargets.slice(0, maxTargets); - sTargets.forEach(target => { - this.apply_damage(target, false); - }); - } - } else { - // 范围伤害:对所有范围内目标造成伤害 - if(IRTargets.length > 0) { - IRTargets.forEach(target => { - this.apply_damage(target, true); - }); - } - } - } + // }); + // // 根据配置的hit_num决定攻击模式 + // const hitNum = SkillSet[this.s_uuid].hit_num || 0; + // if(hitNum > 0) { + // // 限制目标数量:按距离排序,选择最近的N个目标 + // if(IRTargets.length > 0) { + // // 按距离排序(从近到远) + // IRTargets.sort((a, b) => { + // const distanceA = Math.abs(this.node.position.x - a.node.position.x); + // const distanceB = Math.abs(this.node.position.x - b.node.position.x); + // return distanceA - distanceB; + // }); + // // 限制目标数量 + // const maxTargets = Math.min(hitNum, IRTargets.length); + // const sTargets = IRTargets.slice(0, maxTargets); + // sTargets.forEach(target => { + // this.apply_damage(target, false); + // }); + // } + // } else { + // // 范围伤害:对所有范围内目标造成伤害 + // if(IRTargets.length > 0) { + // IRTargets.forEach(target => { + // this.apply_damage(target, true); + // }); + // } + // } + // } //伤害应用 apply_damage(target:HeroViewComp,is_range:boolean=false){ if(target == null) return; if (!this.SConf) return; - - // 检查是否已经命中过这个目标(除非是范围伤害) - const targetId = target.node.uuid; - if(!is_range && this.hitTargets.has(targetId)) { - return; // 已经命中过,跳过 - } - - // 记录命中目标(除非是范围伤害) - if(!is_range) { - this.hitTargets.add(targetId); - } - - console.log(`[skillView] 伤害 [${this.group}][${this.sData.caster.ent.get(HeroAttrsComp).hero_name}][${this.sData.caster.ent.eid}]的 [${this.SConf.name}]对 [${target.box_group}][ ${target.ent.get(HeroAttrsComp).hero_name}][${target.ent.eid}]`); + + // console.log(`[skillView] 伤害 [${this.group}][${this.sData.caster.ent.get(HeroAttrsComp).hero_name}][${this.sData.caster.ent.eid}]的 [${this.SConf.name}]对 [${target.box_group}][ ${target.ent.get(HeroAttrsComp).hero_name}][${target.ent.eid}]`); // if(this.sData.hit_count > this.SConf.hit_num) return 不能超出 最大伤害数量 // 使用伤害队列系统处理伤害 DamageQueueHelper.addDamageToEntity( @@ -149,10 +141,21 @@ export class SkillView extends CCComp { // 更新技能命中次数 this.sData.hit_count++ // 检查技能是否应该销毁 - if( this.sData.hit_count>=(this.SConf.hit+ this.sData.Attrs[Attrs.PUNCTURE])&&(this.SConf.DTType!=DTType.range)&&(this.SConf.EType!=EType.animationEnd)&&(this.SConf.EType!=EType.timeEnd)) this.ent.destroy// 技能命中次数 + if ( + this.sData.hit_count >= (this.SConf.hit + this.sData.Attrs[Attrs.PUNCTURE]) && + (this.SConf.DTType != DTType.range) && + (this.SConf.EType != EType.animationEnd) && + (this.SConf.EType != EType.timeEnd) + ) { + this.ent.destroy(); // 技能命中次数达到上限后销毁 + } } /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ reset() { + const collider = this.getComponent(Collider2D); + if (collider) { + collider.off(Contact2DType.BEGIN_CONTACT); + } this.node.destroy(); } } \ No newline at end of file