From b01a3d2b8489d9fac06fba489a92681f9528f0d1 Mon Sep 17 00:00:00 2001 From: panw Date: Mon, 18 May 2026 10:53:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(skill):=20=E9=87=8D=E5=81=9A=E6=99=AE?= =?UTF-8?q?=E6=94=BB=E5=BC=B9=E9=81=93=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=94=BB=E5=87=BB=E5=91=BD=E4=B8=AD=E8=A1=A8=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增atk_ci普攻预制体,替换原有的atk_light预制体配置 2. 调整普攻预制体的位置、缩放属性,更新技能配置的sp名 3. 重构施法目标坐标计算,修正Y轴高度偏移以命中目标中心 4. 优化线性弹道移动逻辑,统一处理弹道延长和旋转计算 5. 更新攻击动画的帧时长和精灵贴图资源 --- .../game/skill/anm/atk/ball_sred.anim | 37 +- assets/resources/game/skill/atk/atk_ci.prefab | 371 ++++++++++++++++++ .../game/skill/atk/atk_ci.prefab.meta | 13 + .../resources/game/skill/atk/atk_light.prefab | 7 +- assets/script/game/common/config/SkillSet.ts | 2 +- assets/script/game/hero/SCastSystem.ts | 21 +- assets/script/game/skill/SMoveSystem.ts | 39 +- 7 files changed, 438 insertions(+), 52 deletions(-) create mode 100644 assets/resources/game/skill/atk/atk_ci.prefab create mode 100644 assets/resources/game/skill/atk/atk_ci.prefab.meta diff --git a/assets/resources/game/skill/anm/atk/ball_sred.anim b/assets/resources/game/skill/anm/atk/ball_sred.anim index be97a3b9..360fff95 100644 --- a/assets/resources/game/skill/anm/atk/ball_sred.anim +++ b/assets/resources/game/skill/anm/atk/ball_sred.anim @@ -11,7 +11,7 @@ "speed": 1, "wrapMode": 2, "enableTrsBlending": false, - "_duration": 0.3, + "_duration": 0.13333333333333333, "_hash": 500763545, "_tracks": [ { @@ -71,48 +71,23 @@ 0, 0.03333333333333333, 0.06666666666666667, - 0.1, - 0.13333333333333333, - 0.16666666666666666, - 0.2, - 0.23333333333333334, - 0.26666666666666666 + 0.1 ], "_values": [ { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@dce69", + "__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@c85a2", "__expectedType__": "cc.SpriteFrame" }, { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@f3a1e", + "__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@1526a", "__expectedType__": "cc.SpriteFrame" }, { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@d5671", + "__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@fa8fc", "__expectedType__": "cc.SpriteFrame" }, { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@ad18c", - "__expectedType__": "cc.SpriteFrame" - }, - { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@7e2c5", - "__expectedType__": "cc.SpriteFrame" - }, - { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@dd096", - "__expectedType__": "cc.SpriteFrame" - }, - { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@5f8fc", - "__expectedType__": "cc.SpriteFrame" - }, - { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@386fd", - "__expectedType__": "cc.SpriteFrame" - }, - { - "__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@d4c73", + "__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@0d06a", "__expectedType__": "cc.SpriteFrame" } ] diff --git a/assets/resources/game/skill/atk/atk_ci.prefab b/assets/resources/game/skill/atk/atk_ci.prefab new file mode 100644 index 00000000..60b296bf --- /dev/null +++ b/assets/resources/game/skill/atk/atk_ci.prefab @@ -0,0 +1,371 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "atk_ci", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "atk_ci", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + } + ], + "_active": true, + "_components": [ + { + "__id__": 8 + }, + { + "__id__": 10 + }, + { + "__id__": 12 + }, + { + "__id__": 14 + }, + { + "__id__": 16 + } + ], + "_prefab": { + "__id__": 18 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "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.Node", + "_name": "Node", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + }, + { + "__id__": 5 + } + ], + "_prefab": { + "__id__": 7 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 7.98, + "y": 0, + "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__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 4 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 64, + "height": 64 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "93pNmvtQlLSqtTgIepyEmA" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 6 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@c85a2", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": { + "__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6", + "__expectedType__": "cc.SpriteAtlas" + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "12eKc8gltBz50frJCS5+ww" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "3arqAMBz1MvoXBzeDaL5M/", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 9 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 50, + "height": 50 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "63NP9yq3hEUKD/OZZZ5t7x" + }, + { + "__type__": "cc.Animation", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 11 + }, + "playOnLoad": true, + "_clips": [ + { + "__uuid__": "c09c3e6a-dd75-47ec-9db8-cd72c0f9fc59", + "__expectedType__": "cc.AnimationClip" + } + ], + "_defaultClip": { + "__uuid__": "c09c3e6a-dd75-47ec-9db8-cd72c0f9fc59", + "__expectedType__": "cc.AnimationClip" + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "c2RDvksalG2acL3tyGCY0t" + }, + { + "__type__": "57aabs7TE1J5obTAZczc+64", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 13 + }, + "atk_x": 10, + "atk_y": 15, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "60LInmZXxDtKu79AshRG9j" + }, + { + "__type__": "cc.RigidBody2D", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 15 + }, + "enabledContactListener": true, + "bullet": false, + "awakeOnLoad": true, + "_group": 1, + "_type": 1, + "_allowSleep": false, + "_gravityScale": 1, + "_linearDamping": 0, + "_angularDamping": 0, + "_linearVelocity": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_angularVelocity": 0, + "_fixedRotation": false, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e1yBA625RLwLhzo6bLYW7j" + }, + { + "__type__": "cc.BoxCollider2D", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 17 + }, + "tag": 0, + "_group": 1, + "_density": 1, + "_sensor": true, + "_friction": 0.2, + "_restitution": 0, + "_offset": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_size": { + "__type__": "cc.Size", + "width": 50, + "height": 50 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "43ZDJfXX9AX73gyytKQZWm" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "c46/YsCPVOJYA4mWEpNYRx", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/assets/resources/game/skill/atk/atk_ci.prefab.meta b/assets/resources/game/skill/atk/atk_ci.prefab.meta new file mode 100644 index 00000000..1c331f0a --- /dev/null +++ b/assets/resources/game/skill/atk/atk_ci.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "6954a335-aa5e-4fb5-b0ad-64af6f0f4da1", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "atk_ci" + } +} diff --git a/assets/resources/game/skill/atk/atk_light.prefab b/assets/resources/game/skill/atk/atk_light.prefab index 255a00b0..700a713e 100644 --- a/assets/resources/game/skill/atk/atk_light.prefab +++ b/assets/resources/game/skill/atk/atk_light.prefab @@ -95,7 +95,7 @@ }, "_lpos": { "__type__": "cc.Vec3", - "x": -37.68, + "x": 7.98, "y": 0, "z": 0 }, @@ -108,8 +108,8 @@ }, "_lscale": { "__type__": "cc.Vec3", - "x": 0.8, - "y": 1.8, + "x": 0.5, + "y": 1, "z": 1 }, "_mobility": 0, @@ -282,7 +282,6 @@ }, "atk_x": 10, "atk_y": 15, - "debugMode": true, "_id": "" }, { diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index e474d4ad..3e858022 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -172,7 +172,7 @@ export const SkillUpList = { export const SkillSet: Record = { // ========== 基础技能 ========== 6001: { - uuid:6001,name:"普通攻击",sp_name:"atk",icon:"1026",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", + uuid:6001,name:"普通攻击",sp_name:"atk_ci",icon:"1026",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", DTType:DTType.single,ap:100,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.Melee, RType:RType.linear,EType:EType.collision,buffs:[],info:"造成攻击力100%的伤害", }, diff --git a/assets/script/game/hero/SCastSystem.ts b/assets/script/game/hero/SCastSystem.ts index 5f5ce698..c18da730 100644 --- a/assets/script/game/hero/SCastSystem.ts +++ b/assets/script/game/hero/SCastSystem.ts @@ -679,9 +679,22 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate /** 生成沿目标方向的施法目标坐标 */ private buildEnemyCastTargetPos(caster: HeroViewComp, target: HeroViewComp, castRange: number): Vec3 { - const casterPos = caster.node.position; - const targetPos = target.node.position; - const direction = targetPos.x >= casterPos.x ? 1 : -1; - return new Vec3(casterPos.x + direction * castRange, casterPos.y, casterPos.z); + // 直接返回目标的真实坐标,保留其 Y 轴信息,确保能向目标真实所在位置发射 + // 考虑到目前角色的 y 坐标都是脚底(碰撞体底部),为了命中身体中心,给目标 y 加上高度的一半 + let halfHeight = 0; + if (target.node) { + const transform = target.node.getComponent('cc.UITransform') as any; + if (transform) { + halfHeight = transform.height / 2; + } else { + halfHeight = 40; // 如果没有 UITransform,给一个默认高度偏移 + } + } + + const pos = target.node.position.clone(); + pos.y += halfHeight; + + // 至于最终投射物是否要飞出屏幕(例如线性弹道延长至 +-500),由 SMoveSystem 统一处理 + return pos; } } diff --git a/assets/script/game/skill/SMoveSystem.ts b/assets/script/game/skill/SMoveSystem.ts index eef8a165..c24b99e9 100644 --- a/assets/script/game/skill/SMoveSystem.ts +++ b/assets/script/game/skill/SMoveSystem.ts @@ -64,31 +64,46 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate switch(moveComp.runType) { case RType.linear: - // linear类型:根据atk_x和atk_y调整位置 + // linear类型:根据atk_x和atk_y调整起始位置 const adjustedStartPos = v3( - moveComp.startPos.x + moveComp.atk_x, + moveComp.startPos.x + moveComp.atk_x * moveComp.scale, moveComp.startPos.y + moveComp.atk_y, moveComp.startPos.z ); - const adjustedTargetPos = v3( - moveComp.targetPos.x + moveComp.atk_x, - moveComp.targetPos.y + moveComp.atk_y, + + const originTargetPos = v3( + moveComp.targetPos.x, + moveComp.targetPos.y, moveComp.targetPos.z ); - // 如果开启水平移动开关,强制目标Y等于起点Y - if (moveComp.isHorizontal) { - adjustedTargetPos.y = adjustedStartPos.y; + const direction = new Vec3(); + Vec3.subtract(direction, originTargetPos, adjustedStartPos); + + // 延长终止点,统一消亡点的x坐标为 +-500 + const targetX = moveComp.scale > 0 ? 500 : -500; + let targetY = originTargetPos.y; + + if (Math.abs(direction.x) > 0.01) { + const slope = direction.y / direction.x; + targetY = adjustedStartPos.y + slope * (targetX - adjustedStartPos.x); } + + const adjustedTargetPos = v3( + targetX, + targetY, + originTargetPos.z + ); + moveComp.startPos.set(adjustedStartPos); moveComp.targetPos.set(adjustedTargetPos); node.setPosition(adjustedStartPos); // 设置旋转角度 - const direction = new Vec3(); - Vec3.subtract(direction, moveComp.targetPos, moveComp.startPos); - if (direction.length() > 0.01) { - const angle = Math.atan2(direction.y, direction.x) * (180 / Math.PI); + const dirForAngle = new Vec3(); + Vec3.subtract(dirForAngle, adjustedTargetPos, adjustedStartPos); + if (dirForAngle.length() > 0.01) { + const angle = Math.atan2(dirForAngle.y, dirForAngle.x) * (180 / Math.PI); node.angle = angle; } break;