using UnityEngine; using UnityEngine.UI; /// /// 英雄卡片UI控制 /// 显示英雄状态、血条、死亡倒计时、复活按钮 /// public class HeroCardUI : MonoBehaviour { [Header("引用")] public Image iconImage; // 英雄头像 public Image hpFillImage; // 血条填充 public GameObject deathPanel; // 死亡遮罩 public Text reviveTimerText; // 复活倒计时文本 public Button reviveButton; // 立即复活按钮(看广告) public Text reviveCountText; // 剩余复活次数 [Header("绑定的英雄")] public UnitBase heroUnit; // 关联的英雄单位 private WorldHealthBar heroHealthBar; private Vector3 heroSpawnPosition; // 英雄出生位置 [Header("复活设置")] public float reviveTime = 20f; // 自动复活时间 private float reviveTimer = 0f; private bool isDead = false; [Header("广告复活次数")] public int maxAdRevives = 2; // 每局最多2次 private int remainingAdRevives = 2; private void Start() { // 初始化复活次数 remainingAdRevives = maxAdRevives; UpdateReviveCountUI(); // 绑定复活按钮 if (reviveButton != null) { reviveButton.onClick.AddListener(OnReviveButtonClicked); } // 默认隐藏死亡面板 if (deathPanel != null) { deathPanel.SetActive(false); } } private void Update() { if (heroUnit == null || heroHealthBar == null) { return; } // 更新血条 UpdateHealthBar(); // 检查死亡状态 if (heroHealthBar.IsDead && !isDead) { OnHeroDeath(); } // 检查是否已复活(外部复活,例如通过其他系统) if (isDead && !heroHealthBar.IsDead && heroUnit.gameObject.activeSelf) { // 已复活,重置UI状态 isDead = false; if (deathPanel != null) { deathPanel.SetActive(false); } } // 更新复活倒计时 if (isDead) { UpdateReviveTimer(); } } /// /// 设置英雄单位 /// public void SetHero(UnitBase unit, Sprite icon, Vector3 spawnPos) { heroUnit = unit; heroSpawnPosition = spawnPos; if (unit != null) { heroHealthBar = unit.GetComponent(); } // 设置头像 if (iconImage != null && icon != null) { iconImage.sprite = icon; } isDead = false; if (deathPanel != null) { deathPanel.SetActive(false); } } /// /// 更新血条显示 /// private void UpdateHealthBar() { if (hpFillImage != null && heroHealthBar != null) { float fillAmount = heroHealthBar.maxHealth > 0 ? heroHealthBar.currentHealth / heroHealthBar.maxHealth : 0f; hpFillImage.fillAmount = fillAmount; } } /// /// 英雄死亡 /// private void OnHeroDeath() { isDead = true; reviveTimer = reviveTime; // 显示死亡面板 if (deathPanel != null) { deathPanel.SetActive(true); } // 更新复活按钮状态 UpdateReviveButton(); // 阻止英雄单位被销毁(取消延迟销毁) if (heroUnit != null) { // 取消所有Destroy调用 CancelInvoke(); } Debug.Log($"英雄 {heroUnit.name} 死亡,{reviveTime}秒后复活"); } /// /// 更新复活倒计时 /// private void UpdateReviveTimer() { reviveTimer -= Time.deltaTime; // 更新倒计时文本 if (reviveTimerText != null) { reviveTimerText.text = Mathf.CeilToInt(reviveTimer).ToString() + "s"; } // 时间到,自动复活 if (reviveTimer <= 0f) { ReviveHero(); } } /// /// 复活英雄 /// private void ReviveHero() { if (heroUnit == null || heroHealthBar == null) { return; } // 重新激活GameObject(必须先激活,否则无法操作组件) heroUnit.gameObject.SetActive(true); // 重新启用渲染器 foreach (Renderer renderer in heroUnit.GetComponentsInChildren()) { renderer.enabled = true; } // 移动到出生位置 heroUnit.transform.position = heroSpawnPosition; // 重置 NavMeshAgent var navAgent = heroUnit.GetComponent(); if (navAgent != null) { navAgent.enabled = true; // 确保启用 if (!navAgent.isOnNavMesh) { navAgent.enabled = false; navAgent.enabled = true; } navAgent.ResetPath(); // 清空旧路径 } // 重置 UnitBase 状态(关键修复:清空目标让单位重新寻敌) UnitBase unitBase = heroUnit.GetComponent(); if (unitBase != null) { unitBase.enabled = true; // 确保脚本启用 unitBase.target = null; // 清空目标 unitBase.ResetAnchorPosition(); // 重置锚点位置到复活位置(修复一直尝试返回旧锚点的问题) } // 重置 Animator Animator animator = heroUnit.GetComponent(); if (animator != null) { animator.enabled = true; animator.Rebind(); // 重置动画状态 animator.Update(0f); } // 使用WorldHealthBar的Revive方法(会重置isDead并恢复生命) heroHealthBar.Revive(heroHealthBar.maxHealth); // 重新显示血条(修复复活后没有血条的问题) Transform barTransform = heroHealthBar.transform.Find("WorldHealthBar"); if (barTransform != null) { barTransform.gameObject.SetActive(true); } // 重置UI状态 isDead = false; if (deathPanel != null) { deathPanel.SetActive(false); } Debug.Log($"HeroCardUI: {heroUnit.name} 复活完成"); } /// /// 点击立即复活按钮(看广告) /// private void OnReviveButtonClicked() { if (remainingAdRevives <= 0) { Debug.LogWarning("本局广告复活次数已用完"); return; } if (!isDead) { return; } // TODO: 播放广告 Debug.Log("播放广告..."); // 扣除复活次数 remainingAdRevives--; UpdateReviveCountUI(); // 立即复活 ReviveHero(); } /// /// 更新复活按钮状态 /// private void UpdateReviveButton() { if (reviveButton != null) { reviveButton.interactable = remainingAdRevives > 0; } } /// /// 更新剩余复活次数UI /// private void UpdateReviveCountUI() { if (reviveCountText != null) { reviveCountText.text = $"复活 {remainingAdRevives}/{maxAdRevives}"; } UpdateReviveButton(); } /// /// 重置复活次数(新局开始时调用) /// public void ResetReviveCount() { remainingAdRevives = maxAdRevives; UpdateReviveCountUI(); } }