```
feat(gameplay): 实现护盾系统和强化增益选择机制 - 新增护盾功能,包括护盾数值显示和护盾条UI - 重构盾卫技能,实现坚固壁垒技能效果 - 添加暴击率、吸血率等战斗属性 - 优化增益选择界面,新增传奇品质和刷新机制 - 调整材质纹理和文字着色器效果 - 修复金币显示格式问题 ```
This commit is contained in:
1 parent
336ec9980d
commit
48395ab414
27 files changed
+10343
-128
No files matched your search
@@ -10,6 +10,7 @@ public class WorldHealthBar : MonoBehaviour
|
||||
[Min(0f)] public float currentHealth = 100f;
|
||||
|
||||
[Header("护盾")]
|
||||
public float maxShield = 0f;
|
||||
public float currentShield = 0f;
|
||||
|
||||
/// <summary>
|
||||
@@ -18,9 +19,32 @@ public class WorldHealthBar : MonoBehaviour
|
||||
public void AddShield(float amount)
|
||||
{
|
||||
if (amount <= 0f || isDead) return;
|
||||
if (currentShield <= 0f)
|
||||
{
|
||||
maxShield = amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxShield += amount;
|
||||
}
|
||||
currentShield += amount;
|
||||
UpdateFill();
|
||||
Debug.Log($"{gameObject.name} 获得护盾 +{amount:F1},当前护盾: {currentShield:F1}");
|
||||
UpdateShieldFill();
|
||||
Debug.Log($"{gameObject.name} 获得护盾 +{amount:F1},当前护盾: {currentShield:F1}/{maxShield:F1}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 减少或清空护盾
|
||||
/// </summary>
|
||||
public void RemoveShield(float amount)
|
||||
{
|
||||
if (amount <= 0f || currentShield <= 0f) return;
|
||||
currentShield = Mathf.Max(0f, currentShield - amount);
|
||||
if (currentShield <= 0f)
|
||||
{
|
||||
maxShield = 0f;
|
||||
}
|
||||
UpdateShieldFill();
|
||||
}
|
||||
|
||||
// 技能能量上限,英雄默认使用100点;没有技能的小怪可关闭能量条。
|
||||
@@ -74,7 +98,8 @@ public class WorldHealthBar : MonoBehaviour
|
||||
// 描边宽度设为私有常量,所有角色统一使用
|
||||
private const float DamageNumberOutlineWidth = 0.025f; // 从 0.015 增加到 0.025,描边更粗
|
||||
|
||||
// 血条 UI 的像素尺寸,实际显示大小由 worldWidth 控制。
|
||||
// 护盾条高 10 像素,置于血条最上方。
|
||||
private const int ShieldPixelHeight = 10;
|
||||
private const int PixelWidth = 100;
|
||||
private const int PixelHeight = 14;
|
||||
|
||||
@@ -82,7 +107,7 @@ public class WorldHealthBar : MonoBehaviour
|
||||
private const int EnergyPixelWidth = 100; // 改为和血条一样宽
|
||||
private const int EnergyPixelHeight = 12; // 从 8 增加到 12,更明显
|
||||
private const int BarGap = 0; // 改为 0,让血条和能量条紧贴在一起
|
||||
private const int TotalPixelHeight = PixelHeight + BarGap + EnergyPixelHeight;
|
||||
private const int TotalPixelHeight = ShieldPixelHeight + BarGap + PixelHeight + BarGap + EnergyPixelHeight;
|
||||
|
||||
// 世界空间 Canvas,用来承载血条 UI。
|
||||
private Canvas canvas;
|
||||
@@ -90,9 +115,17 @@ public class WorldHealthBar : MonoBehaviour
|
||||
// 血条整体的 RectTransform。
|
||||
private RectTransform barRect;
|
||||
|
||||
// 整体 UI 行节点引用
|
||||
private RectTransform shieldRow;
|
||||
private RectTransform healthRow;
|
||||
private RectTransform energyRow;
|
||||
|
||||
// 绿色血量填充 Image。
|
||||
private Image fillImage;
|
||||
|
||||
// 浅蓝色护盾填充 Image。
|
||||
private Image shieldFillImage;
|
||||
|
||||
// 金色技能能量填充 Image。
|
||||
private Image energyFillImage;
|
||||
|
||||
@@ -218,6 +251,7 @@ public class WorldHealthBar : MonoBehaviour
|
||||
float absorbed = Mathf.Min(currentShield, amount);
|
||||
currentShield -= absorbed;
|
||||
amount -= absorbed;
|
||||
UpdateShieldFill();
|
||||
Debug.Log($"{gameObject.name} 护盾吸收了 {absorbed:F1} 伤害,剩余护盾: {currentShield:F1}");
|
||||
}
|
||||
|
||||
@@ -472,16 +506,32 @@ public class WorldHealthBar : MonoBehaviour
|
||||
canvas.sortingOrder = 100;
|
||||
barObject.GetComponent<CanvasScaler>().dynamicPixelsPerUnit = 10f;
|
||||
barRect = barObject.GetComponent<RectTransform>();
|
||||
barRect.sizeDelta = new Vector2(PixelWidth, showEnergyBar ? TotalPixelHeight : PixelHeight);
|
||||
barRect.sizeDelta = new Vector2(PixelWidth, showEnergyBar ? TotalPixelHeight : (ShieldPixelHeight + PixelHeight));
|
||||
barRect.localScale = Vector3.one * (worldWidth / PixelWidth);
|
||||
barRect.localPosition = GetBarRootPosition();
|
||||
ApplyScaleCompensation();
|
||||
|
||||
RectTransform healthRow = CreateRow(barObject.transform, "HealthBar", PixelWidth, PixelHeight, 0);
|
||||
// 1. 顶层独立护盾条 (ShieldBar)
|
||||
shieldRow = CreateRow(barObject.transform, "ShieldBar", PixelWidth, ShieldPixelHeight, 0);
|
||||
Image shieldBackground = CreateImage("ShieldBorder", shieldRow, RoundedSprite(), borderColor); // 加回黑框
|
||||
SetFullRect(shieldBackground.rectTransform);
|
||||
|
||||
Image shieldInner = CreateImage("ShieldFill", shieldRow, RoundedSprite(), new Color(0f, 0.88f, 1f, 0.95f)); // 亮天蓝色
|
||||
shieldInner.rectTransform.anchorMin = Vector2.zero;
|
||||
shieldInner.rectTransform.anchorMax = Vector2.one;
|
||||
shieldInner.rectTransform.offsetMin = new Vector2(2f, 1f);
|
||||
shieldInner.rectTransform.offsetMax = new Vector2(-2f, -1f);
|
||||
shieldInner.type = Image.Type.Filled;
|
||||
shieldInner.fillMethod = Image.FillMethod.Horizontal;
|
||||
shieldInner.fillOrigin = 0;
|
||||
shieldFillImage = shieldInner;
|
||||
shieldRow.gameObject.SetActive(false); // 默认没有护盾时整体收起隐藏
|
||||
|
||||
// 2. 中层主血条 (HealthBar)
|
||||
healthRow = CreateRow(barObject.transform, "HealthBar", PixelWidth, PixelHeight, ShieldPixelHeight + BarGap);
|
||||
Image background = CreateImage("Border", healthRow, RoundedSprite(), borderColor);
|
||||
SetFullRect(background.rectTransform);
|
||||
|
||||
// 创建填充 Image,颜色暂时使用默认绿色,在 Start() 中根据最终标签设置
|
||||
Image inner = CreateImage("Fill", healthRow, RoundedSprite(), Color.green);
|
||||
inner.rectTransform.anchorMin = Vector2.zero;
|
||||
inner.rectTransform.anchorMax = Vector2.one;
|
||||
@@ -492,6 +542,7 @@ public class WorldHealthBar : MonoBehaviour
|
||||
inner.fillOrigin = 0;
|
||||
fillImage = inner;
|
||||
|
||||
// 3. 底层技能能量条 (EnergyBar)
|
||||
if (!showEnergyBar)
|
||||
{
|
||||
energyFillImage = null;
|
||||
@@ -499,12 +550,12 @@ public class WorldHealthBar : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
RectTransform energyRow = CreateRow(
|
||||
energyRow = CreateRow(
|
||||
barObject.transform,
|
||||
"EnergyBar",
|
||||
EnergyPixelWidth,
|
||||
EnergyPixelHeight,
|
||||
PixelHeight + BarGap);
|
||||
ShieldPixelHeight + BarGap + PixelHeight + BarGap);
|
||||
Image energyBackground = CreateImage("EnergyBorder", energyRow, RoundedSprite(), borderColor);
|
||||
SetFullRect(energyBackground.rectTransform);
|
||||
|
||||
@@ -619,7 +670,7 @@ public class WorldHealthBar : MonoBehaviour
|
||||
// 创建血条左侧的圆圈等级徽章
|
||||
private void CreateLevelBadge(Transform parent)
|
||||
{
|
||||
int badgeSize = 26; // 圆圈徽章直径
|
||||
int badgeSize = 39; // 调整为原来的 1.5 倍 (从 26 增大至 39)
|
||||
GameObject badgeObj = new GameObject("LevelBadge", typeof(RectTransform));
|
||||
badgeObj.transform.SetParent(parent, false);
|
||||
|
||||
@@ -628,7 +679,7 @@ public class WorldHealthBar : MonoBehaviour
|
||||
badgeRect.anchorMax = new Vector2(0f, 1f);
|
||||
badgeRect.pivot = new Vector2(1f, 0.5f); // 右边缘切齐,紧贴血条左边缘
|
||||
badgeRect.sizeDelta = new Vector2(badgeSize, badgeSize);
|
||||
badgeRect.anchoredPosition = new Vector2(2f, -PixelHeight * 0.5f); // 总是对齐第一行血条中心
|
||||
badgeRect.anchoredPosition = new Vector2(2f, -15f); // 居中对齐主血条中心 (posY = -15f)
|
||||
|
||||
// 外层黑边圆圈
|
||||
Image outerCircle = CreateImage("OuterCircle", badgeRect, CircleSprite(), new Color(0.05f, 0.05f, 0.05f, 0.95f));
|
||||
@@ -652,7 +703,7 @@ public class WorldHealthBar : MonoBehaviour
|
||||
levelText = textObj.GetComponent<Text>();
|
||||
levelText.text = unitLevel.ToString();
|
||||
levelText.font = GetBuiltinFont();
|
||||
levelText.fontSize = 18;
|
||||
levelText.fontSize = 26; // 字体同步放大
|
||||
levelText.fontStyle = FontStyle.Bold;
|
||||
levelText.alignment = TextAnchor.MiddleCenter;
|
||||
levelText.color = new Color(0.95f, 0.98f, 0.95f, 1f);
|
||||
@@ -701,6 +752,38 @@ public class WorldHealthBar : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
// 根据当前护盾值更新天蓝色填充比例与显隐。
|
||||
private void UpdateShieldFill()
|
||||
{
|
||||
if (shieldRow != null && shieldFillImage != null)
|
||||
{
|
||||
if (currentShield > 0f)
|
||||
{
|
||||
shieldRow.gameObject.SetActive(true);
|
||||
|
||||
// 1. 护盾条左对齐:锚点改为左上角
|
||||
shieldRow.anchorMin = new Vector2(0f, 1f);
|
||||
shieldRow.anchorMax = new Vector2(0f, 1f);
|
||||
shieldRow.pivot = new Vector2(0f, 1f);
|
||||
shieldRow.anchoredPosition = new Vector2(0f, 0f);
|
||||
|
||||
// 2. 护盾条的物理宽度按 (maxShield / maxHealth) 比例,代表护盾容量占血条的比例
|
||||
float shieldRatio = maxHealth > 0f ? Mathf.Clamp01(maxShield / maxHealth) : 1.0f;
|
||||
float targetWidth = PixelWidth * Mathf.Max(0.05f, shieldRatio);
|
||||
shieldRow.sizeDelta = new Vector2(targetWidth, ShieldPixelHeight);
|
||||
|
||||
// 3. 天蓝色填充条按 (currentShield / maxShield) 动态扣减
|
||||
float fillRatio = maxShield > 0f ? Mathf.Clamp01(currentShield / maxShield) : 1.0f;
|
||||
shieldFillImage.fillAmount = fillRatio;
|
||||
shieldFillImage.SetVerticesDirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
shieldRow.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建并缓存一个直角矩形白色 Sprite,供边框和填充复用。
|
||||
private static Sprite RoundedSprite()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user