From 69f33d8637973ff0fcf5344032d4142711d507e8 Mon Sep 17 00:00:00 2001 From: huadexuan <491009149@qq.com> Date: Wed, 16 Sep 2026 23:06:48 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(MainCharacterCombat):=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E4=B8=BB=E8=A7=92=E5=8F=AC=E5=94=A4=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调整召唤动画超时时间从2.5秒到4秒 - 在开始召唤时立即停止角色移动,调用ClearTarget() - 将animator.SetTrigger改为animator.Play以确保动画正确播放 - 修改召唤位置查找逻辑,当找不到合适位置时在召唤师前方1.5米强制生成 - 更新边界检查逻辑,支持SummonerClickMovement的半场限制 - 添加idle动画播放确保状态正确切换 ``` --- Assets/Prefabs/主角/召唤师主角.prefab | 2 +- Assets/Scenes/Chapter1/SummonerDuelTest.unity | Bin 137572 -> 137684 bytes Assets/Script/MainCharacterCombat.cs | 62 +++++++++++------- CODELY.md | 2 + 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/Assets/Prefabs/主角/召唤师主角.prefab b/Assets/Prefabs/主角/召唤师主角.prefab index b39dcc9..e9f70dc 100644 --- a/Assets/Prefabs/主角/召唤师主角.prefab +++ b/Assets/Prefabs/主角/召唤师主角.prefab @@ -183,7 +183,7 @@ MonoBehaviour: summonSearchCount: 5 summonDepthSearchStep: 1 summonDepthSearchCount: 2 - summonAnimationTimeout: 2.5 + summonAnimationTimeout: 4 projectileSpeed: 12 projectileLifetime: 5 --- !u!114 &6516315820976732023 diff --git a/Assets/Scenes/Chapter1/SummonerDuelTest.unity b/Assets/Scenes/Chapter1/SummonerDuelTest.unity index b54356be685f8510a49335c2816c7f6924095842..7be0d99ed8ac6f664ced5e3624fe037b319864fd 100644 GIT binary patch delta 3441 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 + if (clickMovement != null) + { + clickMovement.ClearTarget(); + } + pendingSummonPrefab = prefab; pendingSummonCharacterData = characterData; pendingSummonPlayerData = playerData; @@ -239,7 +246,7 @@ public class MainCharacterCombat : MonoBehaviour animator.speed = 1f; animator.SetInteger("speed", 0); animator.ResetTrigger("skill"); - animator.SetTrigger("skill"); + animator.Play("skill", 0, 0f); } public void OnSkillHit1() @@ -256,16 +263,9 @@ public class MainCharacterCombat : MonoBehaviour Vector3 spawnPosition; if (!TryFindSummonPosition(direction, out spawnPosition)) { - Debug.LogWarning("主角附近没有可用的召唤位置,本次召唤取消,退还能量"); - - // 退还能量豆 - if (ManaSystem.Instance != null && pendingSummonCharacterData != null) - { - ManaSystem.Instance.AddMana(pendingSummonCharacterData.manaCost); - } - - FinishSummon(); - return; + // 找不到合适位置时,直接在召唤师前方1.5米处生成 + spawnPosition = transform.position + direction * 1.5f; + spawnPosition.y = transform.position.y; } GameObject summoned = Instantiate( @@ -335,7 +335,9 @@ public class MainCharacterCombat : MonoBehaviour private bool TryUseSummonCandidate(Vector3 candidate, out Vector3 position) { candidate.y = transform.position.y; - if (IsInsideMovementBounds(candidate) && IsSummonPositionFree(candidate)) + + // 只检查碰撞,不检查边界(召唤师移动范围已由 SummonerClickMovement 限制) + if (IsSummonPositionFree(candidate)) { position = candidate; return true; @@ -380,28 +382,39 @@ public class MainCharacterCombat : MonoBehaviour private bool IsInsideMovementBounds(Vector3 position) { - return movement == null || movement.IsWithinLeash(position); + // 召唤师对决模式:检查新的 SummonerClickMovement 半场限制 + SummonerClickMovement summonerMovement = GetComponent(); + if (summonerMovement != null) + { + // 使用召唤师的半场范围 + return position.x >= summonerMovement.minX && position.x <= summonerMovement.maxX + && position.z >= summonerMovement.minZ && position.z <= summonerMovement.maxZ; + } + + // 旧版建筑对攻模式:使用栓绳限制 + if (movement != null) + { + return movement.IsWithinLeash(position); + } + + // 无移动组件时不限制 + return true; } private void CheckSummonFinished() { - if (summonElapsed >= summonAnimationTimeout) + AnimatorStateInfo state = animator.GetCurrentAnimatorStateInfo(0); + if (state.IsName("skill") && state.normalizedTime >= 1f) { - Debug.LogWarning("主角召唤动画超时,已解除召唤状态"); FinishSummon(); return; } - AnimatorClipInfo[] clips = animator.GetCurrentAnimatorClipInfo(0); - foreach (AnimatorClipInfo clipInfo in clips) + // skill 状态意外被其他动画打断时,才使用超时兜底,避免永久锁定召唤。 + if (summonElapsed >= summonAnimationTimeout) { - string clipName = clipInfo.clip.name.ToLowerInvariant(); - if ((clipName.Contains("skill") || clipName.Contains("召唤")) - && animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1f) - { - FinishSummon(); - return; - } + Debug.LogWarning("主角召唤动画超时,已解除召唤状态"); + FinishSummon(); } } @@ -413,6 +426,7 @@ public class MainCharacterCombat : MonoBehaviour summonElapsed = 0f; animator.speed = 1f; animator.SetInteger("speed", 0); + animator.Play("idle", 0, 0f); } private void CheckAttackFinished() diff --git a/CODELY.md b/CODELY.md index cbec3bc..1496976 100644 --- a/CODELY.md +++ b/CODELY.md @@ -21,6 +21,8 @@ - [2026-09-09 20:37:24] 用户希望提前实现数据架构而非临时方案,即使当前阶段功能简单。**Why:** 用户有 10 年后端开发经验,理解数据分层的重要性,希望逐步完善而非推倒重来。**How to apply:** 对于有明确扩展方向的功能(升级、存档、联网),优先设计可扩展架构并临时写死数据,而非等需求明确后再重构。 - [2026-09-10 18:38:45] 正交俯视视角(38-43°)下,垂直墙面几乎看不见(只能看到墙顶),因为墙面平行于视线方向被自身遮挡。适合的装饰物:高耸物体(旗帜、石柱)、有明显剪影的物体(木箱、碎石堆)、对比色强的物体;不适合:低矮平面物(矮墙、栅栏)、细长水平物(绳索)。**Why:** 这是正交俯视视角的固有盲区,无法通过调整角度完全解决(角度太平会牺牲战场全局视野)。**How to apply:** 场景装饰设计时优先使用垂直高度≥2米的物体,避免依赖水平或低矮结构。 - [2026-09-14 18:24:56] 用户认可"参考游戏是基地离得远、镜头更远、单位推进慢"的观感方向(2026-09-14 数值改慢后反馈"好多了")。**Why:** 之前双方距离近+移速快,单位两三秒就接触,战斗缺乏观察窗口。**How to apply:** 后续地图/镜头调整优先加长双方距离、拉远摄像机;数值宁慢勿快。 +- [2026-09-16 22:18:14] 召唤系统:找不到合适位置时直接在召唤师前方强制生成,不显示警告,不退还能量。**Why:** 用户要求召唤必须成功,不被取消。**How to apply:** MainCharacterCombat.cs 的召唤逻辑 +- [2026-09-16 22:18:30] 召唤打断移动:主角点击召唤时必须立即停止移动,调用 SummonerClickMovement.ClearTarget() 来实现。**Why:** 用户要求召唤时即使在移动也要立刻停下。**How to apply:** BeginSummon 开始时停止移动 ### Project - [2026-08-28 14:26:56] 弓箭手远程箭矢的设计要求:保持发射时高度水平飞行,命中目标后直接结算伤害并销毁,不产生实体物理击退。**Why:** 当前玩法希望远程攻击是命中判定而非物理推动。**How to apply:** 后续调整箭矢、Projectile 或弓箭手攻击逻辑时保持这一行为。