根据提供的code differences信息,由于没有具体的代码变更内容,我将生成一个通用的commit message模板:
``` docs(readme): 更新文档说明 - 添加项目使用指南 - 完善API接口说明 - 修正错误的配置示例 ``` 注意:由于您提供的code differences部分为空,以上是一个示例模板。当您有具体的代码变更时,请提供详细的变更内容以便生成更准确的commit message。
This commit is contained in:
1 parent
11f1af357d
commit
7d9d0f52d1
83 files changed
+3510
-1493
No files matched your search
@@ -76,13 +76,17 @@ public class UnitBase : MonoBehaviour
|
||||
private bool summonerAttackEnabled = true;
|
||||
|
||||
[Header("无目标回位")]
|
||||
[Tooltip("开启后,当前没有敌方单位时返回生成时的初始格位;不限制正常追击距离。")]
|
||||
[Tooltip("开启后,当前没有敌方单位时返回生成时的初始格位。")]
|
||||
public bool returnToAnchorWhenIdle = false;
|
||||
[Min(0.1f)]
|
||||
public float anchorArrivalDistance = 0.35f;
|
||||
private Vector3 anchorPosition;
|
||||
private bool anchorInitialized;
|
||||
|
||||
[Header("阵位守护")]
|
||||
[Tooltip("开启后,只打「离自己阵位不超过 寻敌视野 detectionRange」的敌人,避免一路推到很远的地方。")]
|
||||
public bool useAnchorLeash = false;
|
||||
|
||||
//角色状态
|
||||
private State state = State.Alert;
|
||||
|
||||
@@ -112,6 +116,8 @@ public class UnitBase : MonoBehaviour
|
||||
private float attackSpeedMultiplier = 1f;
|
||||
private UnitSkill unitSkill;
|
||||
private System.Action skillFinishedCallback;
|
||||
private float skillElapsedTime;
|
||||
private float skillTimeout;
|
||||
|
||||
|
||||
//状态枚举
|
||||
@@ -183,7 +189,7 @@ public class UnitBase : MonoBehaviour
|
||||
navAgent.speed = speed;
|
||||
navAgent.angularSpeed = 120f;
|
||||
navAgent.acceleration = 8f;
|
||||
navAgent.stoppingDistance = attackRange * 0.95f; // 接近攻击范围边缘时停止
|
||||
navAgent.stoppingDistance = NormalStoppingDistance; // 接近攻击范围边缘时停止
|
||||
navAgent.autoBraking = true;
|
||||
|
||||
// NavMesh 使用烘焙平面的高度,不能根据动画帧中的 Renderer 包围盒推算 baseOffset。
|
||||
@@ -287,6 +293,13 @@ public class UnitBase : MonoBehaviour
|
||||
// Attack 状态在上方单独处理,因此不会被这里打断或切换目标。
|
||||
target = FindTarget();
|
||||
|
||||
// 阵位守护:目标离自己阵位超过寻敌视野(detectionRange)就不追了,留在阵位附近
|
||||
if (target != null && useAnchorLeash && anchorInitialized
|
||||
&& IsBeyondLeash(target.transform.position, detectionRange))
|
||||
{
|
||||
target = null;
|
||||
}
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
// 召唤师模式:不主动追击,站定且攻击开关开启时才攻击射程内目标。
|
||||
@@ -374,6 +387,11 @@ public class UnitBase : MonoBehaviour
|
||||
|
||||
public void ApplyStun(float duration)
|
||||
{
|
||||
if (duration <= 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureStatusEffectController().ApplyStun(duration);
|
||||
}
|
||||
|
||||
@@ -455,6 +473,20 @@ public class UnitBase : MonoBehaviour
|
||||
return Vector3.Distance(current, anchor) <= anchorArrivalDistance;
|
||||
}
|
||||
|
||||
/// <summary>某个世界坐标是否离锚点超过了指定距离(只算水平距离)。</summary>
|
||||
private bool IsBeyondLeash(Vector3 worldPosition, float maxDistance)
|
||||
{
|
||||
if (!anchorInitialized) return false;
|
||||
Vector3 anchor = anchorPosition;
|
||||
anchor.y = 0f;
|
||||
Vector3 point = worldPosition;
|
||||
point.y = 0f;
|
||||
return Vector3.Distance(anchor, point) > maxDistance;
|
||||
}
|
||||
|
||||
/// <summary>追击/接敌时用的停靠距离(贴着攻击范围边缘停下)。</summary>
|
||||
private float NormalStoppingDistance => Mathf.Max(0f, attackRange * 0.95f);
|
||||
|
||||
/// <summary>
|
||||
/// 重置锚点位置到当前位置(用于复活等场景)
|
||||
/// </summary>
|
||||
@@ -468,11 +500,7 @@ public class UnitBase : MonoBehaviour
|
||||
{
|
||||
if (navAgent == null || !anchorInitialized)
|
||||
{
|
||||
if (!summonerMode)
|
||||
{
|
||||
animator.SetInteger("speed", 0);
|
||||
animator.speed = 1f; // 重置动画播放速度
|
||||
}
|
||||
RestoreIdleSpeed();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -483,11 +511,7 @@ public class UnitBase : MonoBehaviour
|
||||
|
||||
if (!navAgent.isOnNavMesh)
|
||||
{
|
||||
if (!summonerMode)
|
||||
{
|
||||
animator.SetInteger("speed", 0);
|
||||
animator.speed = 1f; // 重置动画播放速度
|
||||
}
|
||||
RestoreIdleSpeed();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -497,22 +521,41 @@ public class UnitBase : MonoBehaviour
|
||||
navAgent.ResetPath();
|
||||
transform.position = new Vector3(anchorPosition.x, transform.position.y, anchorPosition.z);
|
||||
navAgent.nextPosition = transform.position;
|
||||
if (!summonerMode)
|
||||
{
|
||||
animator.SetInteger("speed", 0);
|
||||
animator.speed = 1f; // 重置动画播放速度
|
||||
}
|
||||
RestoreIdleSpeed();
|
||||
return;
|
||||
}
|
||||
|
||||
navAgent.isStopped = false;
|
||||
// 回位必须贴到锚点:攻击用的停靠距离会把 agent 挡在半路(远程角色尤其明显)
|
||||
navAgent.stoppingDistance = 0f;
|
||||
if (Time.time >= nextPathUpdateTime)
|
||||
{
|
||||
navAgent.SetDestination(anchorPosition);
|
||||
nextPathUpdateTime = Time.time + PathUpdateInterval;
|
||||
}
|
||||
animator.SetInteger("speed", navAgent.velocity.sqrMagnitude > 0.01f ? 1 : 0);
|
||||
animator.speed = 1f; // 确保移动时动画速度正常
|
||||
|
||||
// 用正常速度走回格位
|
||||
navAgent.speed = speed;
|
||||
if (!summonerMode)
|
||||
{
|
||||
animator.SetInteger("speed", navAgent.velocity.sqrMagnitude > 0.01f ? 1 : 0);
|
||||
animator.speed = 1f; // 确保走路动画速度正常
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>回位结束或无法寻路时,把速度和动画恢复成正常站定状态。</summary>
|
||||
private void RestoreIdleSpeed()
|
||||
{
|
||||
if (navAgent != null && navAgent.enabled)
|
||||
{
|
||||
navAgent.speed = speed;
|
||||
navAgent.stoppingDistance = NormalStoppingDistance;
|
||||
}
|
||||
if (!summonerMode && animator != null)
|
||||
{
|
||||
animator.SetInteger("speed", 0);
|
||||
animator.speed = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
//目标决策:只寻找 detectionRange 内的敌方战斗单位;范围内没有敌人时原地待机或回到锚点。
|
||||
@@ -837,21 +880,6 @@ public class UnitBase : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
CrystalMineCapture targetCrystalMine = opponent.GetComponentInParent<CrystalMineCapture>();
|
||||
if (targetCrystalMine != null && targetCrystalMine.ReceiveCaptureDamage(attackPower, gameObject))
|
||||
{
|
||||
RegisterAttackHit();
|
||||
return;
|
||||
}
|
||||
|
||||
BuildingHealth targetBuilding = opponent.GetComponentInParent<BuildingHealth>();
|
||||
if (targetBuilding != null && targetBuilding.ReceiveDamage(attackPower, gameObject))
|
||||
{
|
||||
RegisterAttackHit();
|
||||
return;
|
||||
}
|
||||
|
||||
// 召唤师等特殊单位(有 WorldHealthBar 但没有 UnitBase)
|
||||
WorldHealthBar targetHealthBar = opponent.GetComponentInParent<WorldHealthBar>();
|
||||
if (targetHealthBar != null)
|
||||
{
|
||||
@@ -871,18 +899,6 @@ public class UnitBase : MonoBehaviour
|
||||
UnitBase targetUnit = target.GetComponentInParent<UnitBase>();
|
||||
bool hit = targetUnit != null && targetUnit.ReceiveDamage(damage, gameObject);
|
||||
|
||||
if (!hit)
|
||||
{
|
||||
CrystalMineCapture targetCrystalMine = target.GetComponentInParent<CrystalMineCapture>();
|
||||
hit = targetCrystalMine != null && targetCrystalMine.ReceiveCaptureDamage(damage, gameObject);
|
||||
}
|
||||
|
||||
if (!hit)
|
||||
{
|
||||
BuildingHealth targetBuilding = target.GetComponentInParent<BuildingHealth>();
|
||||
hit = targetBuilding != null && targetBuilding.ReceiveDamage(damage, gameObject);
|
||||
}
|
||||
|
||||
if (!hit)
|
||||
{
|
||||
return;
|
||||
@@ -937,22 +953,9 @@ public class UnitBase : MonoBehaviour
|
||||
}
|
||||
|
||||
UnitBase targetUnit = opponent.GetComponentInParent<UnitBase>();
|
||||
BuildingHealth targetBuilding = opponent.GetComponentInParent<BuildingHealth>();
|
||||
WorldHealthBar healthBar = null;
|
||||
|
||||
if (targetUnit != null)
|
||||
{
|
||||
healthBar = targetUnit.GetComponent<WorldHealthBar>();
|
||||
}
|
||||
else if (targetBuilding != null)
|
||||
{
|
||||
healthBar = targetBuilding.GetComponent<WorldHealthBar>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 召唤师等特殊单位(有 WorldHealthBar 但没有 UnitBase)
|
||||
healthBar = opponent.GetComponentInParent<WorldHealthBar>();
|
||||
}
|
||||
WorldHealthBar healthBar = targetUnit != null
|
||||
? targetUnit.GetComponent<WorldHealthBar>()
|
||||
: opponent.GetComponentInParent<WorldHealthBar>();
|
||||
|
||||
if (healthBar == null || !hitHealthBars.Add(healthBar))
|
||||
{
|
||||
@@ -963,13 +966,8 @@ public class UnitBase : MonoBehaviour
|
||||
{
|
||||
targetUnit.ReceiveDamage(damage, gameObject);
|
||||
}
|
||||
else if (targetBuilding != null)
|
||||
else
|
||||
{
|
||||
targetBuilding.ReceiveDamage(damage, gameObject);
|
||||
}
|
||||
else if (healthBar != null)
|
||||
{
|
||||
// 召唤师等特殊单位
|
||||
healthBar.TakeDamage(damage, gameObject);
|
||||
}
|
||||
}
|
||||
@@ -999,6 +997,7 @@ public class UnitBase : MonoBehaviour
|
||||
// 查找所有带 UnitTeam 的对象(包括单位和召唤师)
|
||||
UnitTeam[] allTeams = FindObjectsOfType<UnitTeam>();
|
||||
HashSet<UnitBase> hitUnits = new HashSet<UnitBase>();
|
||||
HashSet<StatusEffectController> hitStatusEffects = new HashSet<StatusEffectController>();
|
||||
|
||||
foreach (UnitTeam targetTeam in allTeams)
|
||||
{
|
||||
@@ -1031,7 +1030,7 @@ public class UnitBase : MonoBehaviour
|
||||
|
||||
// 召唤师等特殊单位(有 StatusEffectController 但没有 UnitBase)
|
||||
StatusEffectController statusEffect = opponent.GetComponentInParent<StatusEffectController>();
|
||||
if (statusEffect != null)
|
||||
if (statusEffect != null && hitStatusEffects.Add(statusEffect))
|
||||
{
|
||||
statusEffect.ApplyStun(duration);
|
||||
}
|
||||
@@ -1129,6 +1128,11 @@ public class UnitBase : MonoBehaviour
|
||||
|
||||
skillFinishedCallback = onFinished;
|
||||
isPlayingSkill = true;
|
||||
skillElapsedTime = 0f;
|
||||
float animationDuration = GetSkillAnimationDuration();
|
||||
skillTimeout = targetDuration > 0f
|
||||
? targetDuration + 0.5f
|
||||
: Mathf.Max(animationDuration + 0.5f, 2f);
|
||||
state = State.Skill;
|
||||
animator.speed = GetSkillAnimationSpeed(targetDuration);
|
||||
animator.SetInteger("speed", 0);
|
||||
@@ -1145,13 +1149,23 @@ public class UnitBase : MonoBehaviour
|
||||
|
||||
private void CheckSkillAnimationFinished()
|
||||
{
|
||||
if (!isPlayingSkill)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
skillElapsedTime += Time.deltaTime;
|
||||
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
|
||||
if (!stateInfo.IsName("skill") || stateInfo.normalizedTime < 1f)
|
||||
bool animationFinished = stateInfo.IsName("skill") && stateInfo.normalizedTime >= 1f;
|
||||
bool timedOut = skillElapsedTime >= skillTimeout;
|
||||
if (!animationFinished && !timedOut)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
isPlayingSkill = false;
|
||||
skillElapsedTime = 0f;
|
||||
skillTimeout = 0f;
|
||||
state = State.Alert;
|
||||
animator.speed = attackSpeedMultiplier;
|
||||
skillFinishedCallback?.Invoke();
|
||||
@@ -1232,6 +1246,10 @@ public class UnitBase : MonoBehaviour
|
||||
|
||||
if (!navAgent.isOnNavMesh) return;
|
||||
|
||||
// 追击时用正常速度和正常停靠距离(可能刚从回位状态切回来)
|
||||
navAgent.speed = speed;
|
||||
navAgent.stoppingDistance = NormalStoppingDistance;
|
||||
|
||||
// 确保没有被停止
|
||||
if (navAgent.isStopped)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user