From 1a45e91f1a094a963a5beaf790489e8a69630c60 Mon Sep 17 00:00:00 2001 From: panw Date: Mon, 3 Nov 2025 14:47:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(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=E6=B7=BB=E5=8A=A0=E6=94=BB=E5=87=BB=E5=B8=A7=E8=AE=A1?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在SkillView中缓存碰撞体引用并添加攻击帧计数器 - 实现攻击帧事件中动态开启碰撞检测 - 非持续碰撞类型技能在造成伤害后立即关闭碰撞检测 - 清理资源时取消所有定时器 - 调整技能预制体碰撞体位置和大小 - 注释掉Main.ts中的物理调试绘制代码 --- assets/resources/game/skill/atk/atk_s1.prefab | 232 ++++++++++++++++-- assets/script/Main.ts | 4 +- assets/script/game/skill/SkillView.ts | 45 ++-- 3 files changed, 237 insertions(+), 44 deletions(-) diff --git a/assets/resources/game/skill/atk/atk_s1.prefab b/assets/resources/game/skill/atk/atk_s1.prefab index 96133980..c5a74bea 100644 --- a/assets/resources/game/skill/atk/atk_s1.prefab +++ b/assets/resources/game/skill/atk/atk_s1.prefab @@ -20,28 +20,31 @@ "_children": [ { "__id__": 2 + }, + { + "__id__": 8 } ], "_active": true, "_components": [ - { - "__id__": 8 - }, - { - "__id__": 10 - }, - { - "__id__": 12 - }, - { - "__id__": 14 - }, { "__id__": 16 + }, + { + "__id__": 18 + }, + { + "__id__": 20 + }, + { + "__id__": 22 + }, + { + "__id__": 24 } ], "_prefab": { - "__id__": 18 + "__id__": 26 }, "_lpos": { "__type__": "cc.Vec3", @@ -208,6 +211,181 @@ "targetOverrides": null, "nestedPrefabInstanceRoots": null }, + { + "__type__": "cc.Node", + "_name": "T", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 9 + }, + { + "__id__": 11 + }, + { + "__id__": 13 + } + ], + "_prefab": { + "__id__": 15 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 40, + "y": -50, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 8 + }, + "_enabled": true, + "__prefab": { + "__id__": 10 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 80, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8b9HY9QmBA5qB0sBawCFqZ" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 8 + }, + "_enabled": false, + "__prefab": { + "__id__": 12 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@46c83", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e0lXniMh9C77aUoKhV9TG0" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 8 + }, + "_enabled": true, + "__prefab": { + "__id__": 14 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 25, + "_originalHeight": 25, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "efBhSYnd1Kz6YztMYe2EVs" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "0b1uG2sstDMZRfqgTMWTrz", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, { "__type__": "cc.UITransform", "_name": "", @@ -218,17 +396,17 @@ }, "_enabled": true, "__prefab": { - "__id__": 9 + "__id__": 17 }, "_contentSize": { "__type__": "cc.Size", - "width": 200, - "height": 80 + "width": 80, + "height": 100 }, "_anchorPoint": { "__type__": "cc.Vec2", - "x": 0.5, - "y": 0 + "x": 0, + "y": 0.5 }, "_id": "" }, @@ -246,7 +424,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 11 + "__id__": 19 }, "playOnLoad": true, "_clips": [ @@ -275,7 +453,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 13 + "__id__": 21 }, "atk_x": 0, "atk_y": 0, @@ -295,7 +473,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 15 + "__id__": 23 }, "enabledContactListener": true, "bullet": false, @@ -327,9 +505,9 @@ "node": { "__id__": 1 }, - "_enabled": true, + "_enabled": false, "__prefab": { - "__id__": 17 + "__id__": 25 }, "tag": 0, "_group": 1, @@ -339,13 +517,13 @@ "_restitution": 0, "_offset": { "__type__": "cc.Vec2", - "x": 0, - "y": 40 + "x": 40, + "y": 0 }, "_size": { "__type__": "cc.Size", - "width": 200, - "height": 80 + "width": 80, + "height": 100 }, "_id": "" }, diff --git a/assets/script/Main.ts b/assets/script/Main.ts index efc4640f..bb5c2a5b 100644 --- a/assets/script/Main.ts +++ b/assets/script/Main.ts @@ -12,9 +12,9 @@ const { ccclass, property } = _decorator; @ccclass('Main') export class Main extends Root { start() { - PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb + // PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb // |EPhysics2DDrawFlags.Pair - |EPhysics2DDrawFlags.CenterOfMass + // |EPhysics2DDrawFlags.CenterOfMass // |EPhysics2DDrawFlags.Joint // |EPhysics2DDrawFlags.Shape; } diff --git a/assets/script/game/skill/SkillView.ts b/assets/script/game/skill/SkillView.ts index f89233ca..a49c5353 100644 --- a/assets/script/game/skill/SkillView.ts +++ b/assets/script/game/skill/SkillView.ts @@ -3,13 +3,9 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { HeroViewComp } from "../hero/HeroViewComp"; import { DTType, EType, RType, SkillConfig, SkillSet } from "../common/config/SkillSet"; -import { BoxSet, FacSet } from "../common/config/GameSet"; import { SDataCom } from "./SDataCom"; -import { SMoveDataComp } from "./SMoveComp"; import { Attrs } from "../common/config/HeroAttrs"; -import { MonMoveComp } from "../hero/MonMove"; import { HeroAttrsComp } from "../hero/HeroAttrsComp"; -import { HeroMoveComp } from "../hero/HeroMove"; import { DamageQueueHelper } from "../hero/DamageQueueComp"; const { ccclass, property } = _decorator; @@ -29,16 +25,19 @@ export class SkillView extends CCComp { SConf:SkillConfig=null; sData:SDataCom=null; s_uuid:number=1001 + private collider: Collider2D = null; // 缓存碰撞体引用 + private attackFrameCount: number = 0; // 攻击帧计数器 + private maxAttackFrames: number = 1; // 最大攻击帧数,可配置 // 已命中目标追踪,防止重复伤害 start() { this.SConf = SkillSet[this.s_uuid] this.sData=this.ent.get(SDataCom) this.anim=this.node.getComponent(Animation) this.node.active = true; - let collider = this.getComponent(Collider2D); - if(collider) { - collider.group = this.group; - collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); + this.collider = this.getComponent(Collider2D); + if(this.collider) { + this.collider.group = this.group; + this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); } if(this.node.getComponent(Animation)){ let anim = this.node.getComponent(Animation); @@ -78,7 +77,15 @@ export class SkillView extends CCComp { } } // //动画帧事件 atk 触发 - // public atk(args:any){ + public atk(args:any){ + this.attackFrameCount++; + + // 开启碰撞检测 + if(this.collider) { + this.collider.enabled = true; + console.log(`[SkillView] [${this.SConf?.name}] 第${this.attackFrameCount}次攻击帧开启碰撞检测`); + } + // let dis=this.node.getComponent(UITransform).width/2 // let enemys:any=[] // if( this.sData.fac==FacSet.HERO){ @@ -123,12 +130,18 @@ export class SkillView extends CCComp { // }); // } // } - // } + } //伤害应用 apply_damage(target:HeroViewComp,is_range:boolean=false){ if(target == null) return; if (!this.SConf) return; - + + // 对于非持续碰撞类型的技能,在造成伤害后立即关闭碰撞检测 + // 这样可以避免同一帧内的重复伤害 + if(this.SConf.EType !== EType.collision && this.collider) { + this.collider.enabled = false; + console.log(`[SkillView] [${this.SConf.name}] 伤害后关闭碰撞检测`); + } // 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 不能超出 最大伤害数量 // 使用伤害队列系统处理伤害 @@ -152,10 +165,12 @@ export class SkillView extends CCComp { } /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ reset() { - const collider = this.getComponent(Collider2D); - if (collider) { - collider.off(Contact2DType.BEGIN_CONTACT); - } + // 清理碰撞体事件监听 + if (this.collider) { + this.collider.off(Contact2DType.BEGIN_CONTACT); + } + // 取消所有定时器 + this.unscheduleAllCallbacks(); this.node.destroy(); } } \ No newline at end of file