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