feat(MainCharacterCombat): 完善主角召唤系统逻辑

- 调整召唤动画超时时间从2.5秒到4秒
- 在开始召唤时立即停止角色移动,调用ClearTarget()
- 将animator.SetTrigger改为animator.Play以确保动画正确播放
- 修改召唤位置查找逻辑,当找不到合适位置时在召唤师前方1.5米强制生成
- 更新边界检查逻辑,支持SummonerClickMovement的半场限制
- 添加idle动画播放确保状态正确切换
```
This commit is contained in:
huadexuan committed 2026-09-16 23:06:48 +08:00
1 parent f06a1d8f92
commit 69f33d8637
4 files changed
+41 -25

No files matched your search

+38 -24
View File
@@ -230,6 +230,13 @@ public class MainCharacterCombat : MonoBehaviour
return;
}
// 立即停止移动
SummonerClickMovement clickMovement = GetComponent<SummonerClickMovement>();
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<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()
{
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()