refactor(skill): 重构碰撞上限处理与伤害派发逻辑

- 将碰撞上限处理抽离为独立的 handle_collision_limit 方法
- 移除 apply_damage 方法中冗余的销毁逻辑,使职责更清晰
- 优化注释以更准确描述组件职责与关键逻辑
- 添加生命周期保护标记,避免销毁阶段重复处理
This commit is contained in:
panw
2026-03-16 11:40:38 +08:00
parent 4db8788589
commit 5a630b4de5

View File

@@ -10,7 +10,7 @@ import { mLogger } from "../common/Logger";
const { ccclass, property } = _decorator;
/** 视图层对象 */
/** 技能视图组件:负责碰撞窗口、碰撞回调与伤害派发 */
@ccclass('SkillView')
@ecs.register('SkillView', false)
export class SkillView extends CCComp {
@@ -31,7 +31,7 @@ export class SkillView extends CCComp {
private collider: Collider2D = null; // 缓存碰撞体引用
private pendingDisableCollider: boolean = false;
private isDisposing: boolean = false;
// 已命中目标追踪,防止重复伤害
// 生命周期保护标记,避免在销毁阶段重复处理碰撞
init() {
this.SConf = SkillSet[this.s_uuid]
this.sData = this.ent.get(SDataCom)
@@ -75,13 +75,14 @@ export class SkillView extends CCComp {
if (oCol.group === seCol.group) return;
if (this.pendingDisableCollider) return;
if (this.sData.hit_count >= this.sData.max_hit_count) {
this.close_collider();
this.handle_collision_limit();
return;
}
this.sData.hit_count++;
if (this.sData.hit_count >= this.sData.max_hit_count) {
this.close_collider();
this.handle_collision_limit();
}
// 命中次数按碰撞事件统计:不依赖是否最终造成伤害
// 不是 HeroViewComp直接忽略
if (!targetView) return;
// 🔥 方案A防御性检查 - 在获取model前强制检查ent是否存在
@@ -99,12 +100,13 @@ export class SkillView extends CCComp {
}
onAnimationFinished(){
// animationEnd 类型:动画结束后再关闭碰撞并销毁
if(this.SConf.EType==EType.animationEnd){
this.disable_collider_now();
this.ent.destroy()
}
}
// //动画帧事件 atk 触发
// 动画帧事件 atk:仅负责开启一帧碰撞窗口,不负责伤害与计数
public atk(args:any){
if(!this.SConf) return;
if(this.SConf.EType==EType.collision) return
@@ -117,7 +119,7 @@ export class SkillView extends CCComp {
}, 0);
}
}
//伤害应用
// 仅负责伤害派发,不处理命中次数与实体销毁
apply_damage(target:HeroViewComp,is_range:boolean=false){
if(target == null) return;
// 安全检查:如果目标实体已不存在,直接返回
@@ -138,19 +140,6 @@ export class SkillView extends CCComp {
this.sData.ext_dmg,
this.sData.dmg_ratio,
);
if (
(this.SConf.DTType != DTType.range) &&
(this.SConf.EType != EType.animationEnd) &&
(this.SConf.EType != EType.timeEnd)
) {
// 修复:物理回调中不能直接销毁刚体,需延迟到下一帧
this.close_collider();
this.scheduleOnce(() => {
if (this.ent) {
this.ent.destroy();
}
}, 0);
}
}
close_collider(){
if (!this.collider) return;
@@ -165,6 +154,18 @@ export class SkillView extends CCComp {
this.isDisposing = true;
this.close_collider();
}
// 碰撞上限收口先关碰撞collision 类型再延迟销毁实体
private handle_collision_limit() {
this.close_collider();
if (this.SConf?.EType !== EType.collision) return;
if (this.isDisposing) return;
this.isDisposing = true;
this.scheduleOnce(() => {
if (this.ent) {
this.ent.destroy();
}
}, 0);
}
private enable_collider_safely(): boolean {
if (!this.collider || !this.collider.isValid) return false;
if (this.isDisposing) return false;