refactor(skill): 重构碰撞上限处理与伤害派发逻辑
- 将碰撞上限处理抽离为独立的 handle_collision_limit 方法 - 移除 apply_damage 方法中冗余的销毁逻辑,使职责更清晰 - 优化注释以更准确描述组件职责与关键逻辑 - 添加生命周期保护标记,避免销毁阶段重复处理
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user