根据提供的code differences信息,由于没有具体的代码变更内容,我将生成一个通用的commit message模板:

```
docs(changelog): 更新项目变更日志

- 添加新的版本记录
- 修正已知问题描述
- 更新功能特性说明
```

注意:由于您提供的code differences部分为空,以上是一个示例模板。实际使用时请根据具体的代码变更内容来填写相应的type、scope、subject和body信息。
This commit is contained in:
huadexuan committed 2026-09-17 14:03:34 +08:00
1 parent 69f33d8637
commit 951ba49c79
26 files changed
+942 -455

No files matched your search

+89 -35
View File
@@ -342,48 +342,50 @@ public class UnitBase : MonoBehaviour
//根据自身Tag找到敌对Tag
private string GetOpponentTag()
{
if (CompareTag("Friend"))
{
return "Enemy";
}
if (CompareTag("Enemy"))
{
return "Friend";
}
// 已弃用:改用阵营 ID 系统,不再依赖 Tag 判断敌我
// 保留此方法是为了兼容旧代码,但不应再被调用
Debug.LogWarning("GetOpponentTag() 已弃用,请使用阵营 ID 系统");
return null;
}
//查找距离自己最近的敌对目标
//查找距离自己最近的敌对目标(使用阵营 ID 判断)
private GameObject FindNearestOpponent()
{
string opponentTag = GetOpponentTag();
if (string.IsNullOrEmpty(opponentTag))
var myTeam = GetComponent<UnitTeam>();
if (myTeam == null)
{
Debug.LogWarning($"{gameObject.name} 缺少 UnitTeam 组件,无法查找敌人");
return null;
}
GameObject nearestOpponent = null;
float nearestSqrDistance = float.PositiveInfinity;
GameObject[] opponents = GameObject.FindGameObjectsWithTag(opponentTag);
foreach (var opponent in opponents)
// 查找所有 UnitTeam 组件(不再依赖 Tag)
UnitTeam[] allUnits = FindObjectsOfType<UnitTeam>();
foreach (var unit in allUnits)
{
//排除自己以及自己所在层级中的对象
if (opponent == gameObject || opponent.transform.root == transform.root)
// 跳过自己和友军
if (unit.gameObject == gameObject || !myTeam.IsEnemy(unit.gameObject))
{
continue;
}
float sqrDistance = (opponent.transform.position - transform.position).sqrMagnitude;
//排除自己所在层级中的对象
if (unit.transform.root == transform.root)
{
continue;
}
float sqrDistance = (unit.transform.position - transform.position).sqrMagnitude;
//加入确定性分散偏移:让不同单位偏好不同目标,避免全部涌向同一个敌人
float bias = ((uint)(gameObject.GetInstanceID() * 7919) ^ (uint)(opponent.GetInstanceID())) % 10u / 10f * targetSpreadBias;
float bias = ((uint)(gameObject.GetInstanceID() * 7919) ^ (uint)(unit.gameObject.GetInstanceID())) % 10u / 10f * targetSpreadBias;
float adjustedSqrDistance = sqrDistance + bias;
if (adjustedSqrDistance < nearestSqrDistance)
{
nearestSqrDistance = adjustedSqrDistance;
nearestOpponent = opponent;
nearestOpponent = unit.gameObject;
}
}
@@ -651,6 +653,15 @@ public class UnitBase : MonoBehaviour
if (targetBuilding != null && targetBuilding.ReceiveDamage(attackPower, gameObject))
{
RegisterAttackHit();
return;
}
// 召唤师等特殊单位(有 WorldHealthBar 但没有 UnitBase)
WorldHealthBar targetHealthBar = opponent.GetComponentInParent<WorldHealthBar>();
if (targetHealthBar != null)
{
targetHealthBar.TakeDamage(attackPower, gameObject);
RegisterAttackHit();
}
}
@@ -689,23 +700,33 @@ public class UnitBase : MonoBehaviour
return;
}
string opponentTag = GetOpponentTag();
if (string.IsNullOrEmpty(opponentTag))
UnitTeam myTeam = GetComponent<UnitTeam>();
if (myTeam == null)
{
return;
}
float clampedRadius = Mathf.Max(0f, radius);
float radiusSquared = clampedRadius * clampedRadius;
GameObject[] opponents = GameObject.FindGameObjectsWithTag(opponentTag);
// 查找所有带 UnitTeam 的对象(包括单位和召唤师)
UnitTeam[] allTeams = FindObjectsOfType<UnitTeam>();
HashSet<WorldHealthBar> hitHealthBars = new HashSet<WorldHealthBar>();
foreach (GameObject opponent in opponents)
foreach (UnitTeam targetTeam in allTeams)
{
GameObject opponent = targetTeam.gameObject;
if (opponent == null || opponent == gameObject || opponent.transform.root == transform.root)
{
continue;
}
// 检查是否是敌人
if (!myTeam.IsEnemy(opponent))
{
continue;
}
Vector3 offset = opponent.transform.position - transform.position;
offset.y = 0f;
@@ -716,9 +737,21 @@ public class UnitBase : MonoBehaviour
UnitBase targetUnit = opponent.GetComponentInParent<UnitBase>();
BuildingHealth targetBuilding = opponent.GetComponentInParent<BuildingHealth>();
WorldHealthBar healthBar = targetUnit != null
? targetUnit.GetComponent<WorldHealthBar>()
: targetBuilding != null ? targetBuilding.GetComponent<WorldHealthBar>() : null;
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>();
}
if (healthBar == null || !hitHealthBars.Add(healthBar))
{
@@ -729,10 +762,15 @@ public class UnitBase : MonoBehaviour
{
targetUnit.ReceiveDamage(damage, gameObject);
}
else
else if (targetBuilding != null)
{
targetBuilding.ReceiveDamage(damage, gameObject);
}
else if (healthBar != null)
{
// 召唤师等特殊单位
healthBar.TakeDamage(damage, gameObject);
}
}
if (registerEnergy)
@@ -748,23 +786,33 @@ public class UnitBase : MonoBehaviour
return;
}
string opponentTag = GetOpponentTag();
if (string.IsNullOrEmpty(opponentTag))
UnitTeam myTeam = GetComponent<UnitTeam>();
if (myTeam == null)
{
return;
}
float clampedRadius = Mathf.Max(0f, radius);
float radiusSquared = clampedRadius * clampedRadius;
GameObject[] opponents = GameObject.FindGameObjectsWithTag(opponentTag);
// 查找所有带 UnitTeam 的对象(包括单位和召唤师)
UnitTeam[] allTeams = FindObjectsOfType<UnitTeam>();
HashSet<UnitBase> hitUnits = new HashSet<UnitBase>();
foreach (GameObject opponent in opponents)
foreach (UnitTeam targetTeam in allTeams)
{
GameObject opponent = targetTeam.gameObject;
if (opponent == null || opponent == gameObject || opponent.transform.root == transform.root)
{
continue;
}
// 检查是否是敌人
if (!myTeam.IsEnemy(opponent))
{
continue;
}
Vector3 offset = opponent.transform.position - transform.position;
offset.y = 0f;
@@ -774,12 +822,18 @@ public class UnitBase : MonoBehaviour
}
UnitBase unit = opponent.GetComponentInParent<UnitBase>();
if (unit == null || !hitUnits.Add(unit))
if (unit != null && hitUnits.Add(unit))
{
unit.ApplyStun(duration);
continue;
}
unit.ApplyStun(duration);
// 召唤师等特殊单位(有 StatusEffectController 但没有 UnitBase)
StatusEffectController statusEffect = opponent.GetComponentInParent<StatusEffectController>();
if (statusEffect != null)
{
statusEffect.ApplyStun(duration);
}
}
}