```
feat(MainCharacterCombat): 完善主角召唤系统逻辑 - 调整召唤动画超时时间从2.5秒到4秒 - 在开始召唤时立即停止角色移动,调用ClearTarget() - 将animator.SetTrigger改为animator.Play以确保动画正确播放 - 修改召唤位置查找逻辑,当找不到合适位置时在召唤师前方1.5米强制生成 - 更新边界检查逻辑,支持SummonerClickMovement的半场限制 - 添加idle动画播放确保状态正确切换 ```
This commit is contained in:
1 parent
f06a1d8f92
commit
69f33d8637
4 files changed
+41
-25
No files matched your search
@@ -183,7 +183,7 @@ MonoBehaviour:
|
|||||||
summonSearchCount: 5
|
summonSearchCount: 5
|
||||||
summonDepthSearchStep: 1
|
summonDepthSearchStep: 1
|
||||||
summonDepthSearchCount: 2
|
summonDepthSearchCount: 2
|
||||||
summonAnimationTimeout: 2.5
|
summonAnimationTimeout: 4
|
||||||
projectileSpeed: 12
|
projectileSpeed: 12
|
||||||
projectileLifetime: 5
|
projectileLifetime: 5
|
||||||
--- !u!114 &6516315820976732023
|
--- !u!114 &6516315820976732023
|
||||||
|
|||||||
Binary file not shown.
@@ -230,6 +230,13 @@ public class MainCharacterCombat : MonoBehaviour
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 立即停止移动
|
||||||
|
SummonerClickMovement clickMovement = GetComponent<SummonerClickMovement>();
|
||||||
|
if (clickMovement != null)
|
||||||
|
{
|
||||||
|
clickMovement.ClearTarget();
|
||||||
|
}
|
||||||
|
|
||||||
pendingSummonPrefab = prefab;
|
pendingSummonPrefab = prefab;
|
||||||
pendingSummonCharacterData = characterData;
|
pendingSummonCharacterData = characterData;
|
||||||
pendingSummonPlayerData = playerData;
|
pendingSummonPlayerData = playerData;
|
||||||
@@ -239,7 +246,7 @@ public class MainCharacterCombat : MonoBehaviour
|
|||||||
animator.speed = 1f;
|
animator.speed = 1f;
|
||||||
animator.SetInteger("speed", 0);
|
animator.SetInteger("speed", 0);
|
||||||
animator.ResetTrigger("skill");
|
animator.ResetTrigger("skill");
|
||||||
animator.SetTrigger("skill");
|
animator.Play("skill", 0, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnSkillHit1()
|
public void OnSkillHit1()
|
||||||
@@ -256,16 +263,9 @@ public class MainCharacterCombat : MonoBehaviour
|
|||||||
Vector3 spawnPosition;
|
Vector3 spawnPosition;
|
||||||
if (!TryFindSummonPosition(direction, out spawnPosition))
|
if (!TryFindSummonPosition(direction, out spawnPosition))
|
||||||
{
|
{
|
||||||
Debug.LogWarning("主角附近没有可用的召唤位置,本次召唤取消,退还能量");
|
// 找不到合适位置时,直接在召唤师前方1.5米处生成
|
||||||
|
spawnPosition = transform.position + direction * 1.5f;
|
||||||
// 退还能量豆
|
spawnPosition.y = transform.position.y;
|
||||||
if (ManaSystem.Instance != null && pendingSummonCharacterData != null)
|
|
||||||
{
|
|
||||||
ManaSystem.Instance.AddMana(pendingSummonCharacterData.manaCost);
|
|
||||||
}
|
|
||||||
|
|
||||||
FinishSummon();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObject summoned = Instantiate(
|
GameObject summoned = Instantiate(
|
||||||
@@ -335,7 +335,9 @@ public class MainCharacterCombat : MonoBehaviour
|
|||||||
private bool TryUseSummonCandidate(Vector3 candidate, out Vector3 position)
|
private bool TryUseSummonCandidate(Vector3 candidate, out Vector3 position)
|
||||||
{
|
{
|
||||||
candidate.y = transform.position.y;
|
candidate.y = transform.position.y;
|
||||||
if (IsInsideMovementBounds(candidate) && IsSummonPositionFree(candidate))
|
|
||||||
|
// 只检查碰撞,不检查边界(召唤师移动范围已由 SummonerClickMovement 限制)
|
||||||
|
if (IsSummonPositionFree(candidate))
|
||||||
{
|
{
|
||||||
position = candidate;
|
position = candidate;
|
||||||
return true;
|
return true;
|
||||||
@@ -380,28 +382,39 @@ public class MainCharacterCombat : MonoBehaviour
|
|||||||
|
|
||||||
private bool IsInsideMovementBounds(Vector3 position)
|
private bool IsInsideMovementBounds(Vector3 position)
|
||||||
{
|
{
|
||||||
return movement == null || movement.IsWithinLeash(position);
|
// 召唤师对决模式:检查新的 SummonerClickMovement 半场限制
|
||||||
|
SummonerClickMovement summonerMovement = GetComponent<SummonerClickMovement>();
|
||||||
|
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()
|
private void CheckSummonFinished()
|
||||||
{
|
{
|
||||||
if (summonElapsed >= summonAnimationTimeout)
|
AnimatorStateInfo state = animator.GetCurrentAnimatorStateInfo(0);
|
||||||
|
if (state.IsName("skill") && state.normalizedTime >= 1f)
|
||||||
{
|
{
|
||||||
Debug.LogWarning("主角召唤动画超时,已解除召唤状态");
|
|
||||||
FinishSummon();
|
FinishSummon();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatorClipInfo[] clips = animator.GetCurrentAnimatorClipInfo(0);
|
// skill 状态意外被其他动画打断时,才使用超时兜底,避免永久锁定召唤。
|
||||||
foreach (AnimatorClipInfo clipInfo in clips)
|
if (summonElapsed >= summonAnimationTimeout)
|
||||||
{
|
{
|
||||||
string clipName = clipInfo.clip.name.ToLowerInvariant();
|
Debug.LogWarning("主角召唤动画超时,已解除召唤状态");
|
||||||
if ((clipName.Contains("skill") || clipName.Contains("召唤"))
|
FinishSummon();
|
||||||
&& animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1f)
|
|
||||||
{
|
|
||||||
FinishSummon();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,6 +426,7 @@ public class MainCharacterCombat : MonoBehaviour
|
|||||||
summonElapsed = 0f;
|
summonElapsed = 0f;
|
||||||
animator.speed = 1f;
|
animator.speed = 1f;
|
||||||
animator.SetInteger("speed", 0);
|
animator.SetInteger("speed", 0);
|
||||||
|
animator.Play("idle", 0, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckAttackFinished()
|
private void CheckAttackFinished()
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
- [2026-09-09 20:37:24] 用户希望提前实现数据架构而非临时方案,即使当前阶段功能简单。**Why:** 用户有 10 年后端开发经验,理解数据分层的重要性,希望逐步完善而非推倒重来。**How to apply:** 对于有明确扩展方向的功能(升级、存档、联网),优先设计可扩展架构并临时写死数据,而非等需求明确后再重构。
|
- [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-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-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
|
### Project
|
||||||
- [2026-08-28 14:26:56] 弓箭手远程箭矢的设计要求:保持发射时高度水平飞行,命中目标后直接结算伤害并销毁,不产生实体物理击退。**Why:** 当前玩法希望远程攻击是命中判定而非物理推动。**How to apply:** 后续调整箭矢、Projectile 或弓箭手攻击逻辑时保持这一行为。
|
- [2026-08-28 14:26:56] 弓箭手远程箭矢的设计要求:保持发射时高度水平飞行,命中目标后直接结算伤害并销毁,不产生实体物理击退。**Why:** 当前玩法希望远程攻击是命中判定而非物理推动。**How to apply:** 后续调整箭矢、Projectile 或弓箭手攻击逻辑时保持这一行为。
|
||||||
|
|||||||
Reference in new issue
Block a user