feat(UnitBase): 添加单位分散机制和目标选择偏移

- 新增阵型分散参数:separationRadius、separationWeight、targetSpreadBias
- 实现ComputeSeparation方法计算友军分离力,避免单位扎堆
- 添加确定性分散偏移,让不同单位偏好不同目标,避免全部涌向同一敌人
- 在移动逻辑中集成分离向量计算

feat(WorldHealthBar): 实现伤害数字显示系统

- 添加伤害数字相关配置参数:showDamageNumbers、damageNumberDuration等
- 实现TakeDamage和Heal方法中的伤害数字生成逻辑
- 创建DamageNumber组件处理数字的上升、缩放、淡出动画
- 实现白字黑边效果,使用TextMesh副本组合方式实现描边

refactor(CoreBattleTest): 更新AI巡逻和检测参数

- 将clickStopDistance替换为patrolStopDistance、patrolPause、patrolRadius
- 添加leashRadius和friendlyBuildingTag参数
- 为攻击单位增加detectRange检测范围参数

chore(dependencies): 更新包管理依赖配置

- 添加TJGenerators和CodelyBridge包引用
- 调整包依赖顺序,保持XR模块引用

docs(CODELY): 更新开发日志记录

- 添加建筑系统核心脚本实现说明
- 记录NavMesh烘焙问题及解决方案
- 详细说明伤害数字系统的实现要点和技术难点
```
This commit is contained in:
huadexuan committed 2026-09-14 23:11:35 +08:00
1 parent 8d43961f67
commit 4e892d74c4
7 files changed
+2060 -13

No files matched your search

+58 -2
View File
@@ -67,6 +67,13 @@ public class UnitBase : MonoBehaviour
[Min(0f)]
public float energyPerAttack = 20f;
[Header("阵型分散")]
[Min(0f)] public float separationRadius = 1.5f;
[Min(0f)] public float separationWeight = 3f;
[Min(0f)] public float targetSpreadBias = 6f;
private static Collider[] s_separationBuffer = new Collider[30];
//角色状态
private State state = State.Alert;
@@ -305,9 +312,12 @@ public class UnitBase : MonoBehaviour
}
float sqrDistance = (opponent.transform.position - transform.position).sqrMagnitude;
if (sqrDistance < nearestSqrDistance)
//加入确定性分散偏移:让不同单位偏好不同目标,避免全部涌向同一个敌人
float bias = ((uint)(gameObject.GetInstanceID() * 7919) ^ (uint)(opponent.GetInstanceID())) % 10u / 10f * targetSpreadBias;
float adjustedSqrDistance = sqrDistance + bias;
if (adjustedSqrDistance < nearestSqrDistance)
{
nearestSqrDistance = sqrDistance;
nearestSqrDistance = adjustedSqrDistance;
nearestOpponent = opponent;
}
}
@@ -882,6 +892,15 @@ public class UnitBase : MonoBehaviour
void move(Vector3 movement)
{
movement.y = 0;
//友军分离力:与过近的同阵营单位互相推开,避免扎堆
Vector3 separation = ComputeSeparation();
if (separation.sqrMagnitude > 0.0001f)
{
movement += separation * separationWeight;
movement.y = 0;
}
if (movement == Vector3.zero)
{
animator.SetInteger("speed", 0);
@@ -900,6 +919,43 @@ public class UnitBase : MonoBehaviour
transform.rotation = Quaternion.Euler(0f, movementRotation.eulerAngles.y, 0f);
}
//计算与附近同阵营单位的分离向量;越近推力越大。
private Vector3 ComputeSeparation()
{
if (separationRadius <= 0f)
{
return Vector3.zero;
}
int hitCount = Physics.OverlapSphereNonAlloc(transform.position, separationRadius, s_separationBuffer);
Vector3 separation = Vector3.zero;
for (int i = 0; i < hitCount; i++)
{
Collider other = s_separationBuffer[i];
if (other == null || other.gameObject == gameObject)
{
continue;
}
//只推开同阵营单位,敌人间的碰撞由CharacterController自然阻挡
if (!other.CompareTag(gameObject.tag))
{
continue;
}
Vector3 diff = transform.position - other.transform.position;
diff.y = 0f;
float distance = diff.magnitude;
if (distance > 0.01f && distance < separationRadius)
{
separation += diff / distance * (separationRadius - distance);
}
}
return separation;
}
private float getVerticalVelocity()
{