using UnityEngine; using DarkTonic.MasterAudio; using DG.Tweening; using System; /// /// 水晶雕像控制器 - 单个雕像的控制逻辑 /// 包含血量、裂痕效果、击打反馈等功能 /// public class CrystalStatue : MonoBehaviour { #region 配置 [Header("雕像类型")] public StatueType statueType; public bool isTarget; // 是否是目标雕像 [Header("血量配置")] public int maxHealth = 3; private int currentHealth; [Header("裂痕效果")] public Renderer statueRenderer; public Material[] crackMaterials; // 0=正常, 1=裂痕1, 2=裂痕2, 3=碎裂前 public GameObject[] crackDecals; // 裂痕贴花对象 [Header("特效")] public ParticleSystem hitParticle; // 击打粒子效果 public ParticleSystem breakParticle; // 碎裂粒子效果 public ParticleSystem evilLaughParticle; // 狞笑粒子效果(失败时) [Header("音效")] public string hitSound = "2.1"; // 击打音效 public string crackSound = "2.1"; // 裂痕音效 public string breakSound = "2.2"; // 碎裂音效 public string evilLaughSound = "2.3"; // 狞笑音效 [Header("动画")] public Animator animator; public string hitAnimTrigger = "Hit"; public string breakAnimTrigger = "Break"; public string evilLaughAnimTrigger = "EvilLaugh"; [Header("视觉效果")] public GameObject heartObject; // 心脏显示对象(第三轮用) public GameObject handsObject; // 双手显示对象(第二轮用) public ParticleSystem specialEffect; // 特殊效果(心脏跳动/手部特效) [Header("表情区分(第一轮用)")] public GameObject evilFaceObject; // 邪恶表情对象 [Header("碎裂配置")] public float breakDuration = 1f; public float disappearDelay = 0.5f; [Header("震动配置")] public float hitShakeDuration = 0.2f; // 击打震动持续时间 public float hitShakeStrength = 0.1f; // 击打震动强度 public int hitShakeVibrato = 10; // 震动频率 public float hitShakeRandomness = 90f; // 震动随机性 [Header("调试")] public bool debugMode = true; #endregion #region 状态 public enum StatueType { Normal, // 普通雕像 EvilFace, // 邪恶表情 EvilHands, // 恶毒双手 JealousHeart // 嫉妒之心 } public enum StatueState { Idle, Hit, Breaking, Broken, EvilLaugh } public StatueState currentState = StatueState.Idle; // 当前裂痕等级 private int crackLevel = 0; // 是否可以被击打 private bool canHit = true; // 事件回调 public Action OnStatueBroken; // 雕像碎裂回调(雕像, 是否是目标) #endregion #region Unity生命周期 private void Awake() { if (animator == null) animator = GetComponent(); if (statueRenderer == null) statueRenderer = GetComponentInChildren(); } private void Start() { currentHealth = maxHealth; crackLevel = 0; canHit = true; currentState = StatueState.Idle; } #endregion #region 初始化 /// /// 初始化雕像 /// public void Initialize(StatueType type, bool isTarget) { this.statueType = type; this.isTarget = isTarget; currentHealth = maxHealth; crackLevel = 0; canHit = true; currentState = StatueState.Idle; // 根据类型设置视觉效果 SetupVisualsByType(); if (debugMode) Debug.Log($"[CrystalStatue] 初始化雕像: {type}, 是否目标: {isTarget}"); } /// /// 根据类型设置视觉效果 /// private void SetupVisualsByType() { // 隐藏所有特殊部件 if (heartObject != null) heartObject.SetActive(false); if (handsObject != null) handsObject.SetActive(false); if (evilFaceObject != null) evilFaceObject.SetActive(false); if (specialEffect != null) specialEffect.Stop(); if (isTarget) { // 根据类型显示对应部件 switch (statueType) { case StatueType.EvilFace: // 第一轮:邪恶表情区分 // 目标雕像显示邪恶表情,非目标显示和善表情 if (isTarget) { // 邪恶表情 if (evilFaceObject != null) evilFaceObject.SetActive(true); if (debugMode) Debug.Log("[CrystalStatue] 设置邪恶表情(目标雕像)"); } else { if (debugMode) Debug.Log("[CrystalStatue] 设置和善表情(非目标雕像)"); } break; case StatueType.EvilHands: // 第二轮:恶毒双手区分 if (handsObject != null) handsObject.SetActive(true); if (specialEffect != null && isTarget) specialEffect.Play(); break; case StatueType.JealousHeart: // 第三轮:嫉妒之心区分 if (heartObject != null) heartObject.SetActive(true); if (specialEffect != null && isTarget) specialEffect.Play(); break; } } // 重置裂痕 UpdateCrackVisual(0); } #endregion #region 击打处理 /// /// 玩家击中雕像 /// public void OnPlayerHit() { if (!canHit || currentState == StatueState.Broken) { if (debugMode) Debug.Log("[CrystalStatue] 雕像不可被击打"); return; } currentState = StatueState.Hit; currentHealth--; crackLevel = maxHealth - currentHealth; if (debugMode) Debug.Log($"[CrystalStatue] 雕像被击打! 剩余血量: {currentHealth}, 裂痕等级: {crackLevel}"); // 播放击打音效 PlayHitSound(); // 播放击打特效 PlayHitEffect(); // 播放击打动画 PlayHitAnimation(); // 更新裂痕视觉效果 UpdateCrackVisual(crackLevel); // 检查是否碎裂 if (currentHealth <= 0) { Break(); } else { // 短暂冷却 canHit = false; DOVirtual.DelayedCall(0.2f, () => { canHit = true; if (currentHealth > 0) currentState = StatueState.Idle; }); } } /// /// 雕像碎裂 /// public void Break() { currentState = StatueState.Breaking; canHit = false; if (debugMode) Debug.Log($"[CrystalStatue] 雕像碎裂! 是否目标: {isTarget}"); // 播放碎裂音效 PlayBreakSound(); // 播放碎裂特效 PlayBreakEffect(); // 播放碎裂动画 PlayBreakAnimation(); // 延迟后触发回调 DOVirtual.DelayedCall(disappearDelay, () => { currentState = StatueState.Broken; OnStatueBroken?.Invoke(this, isTarget); }); } /// /// 播放邪恶狞笑(失败时) /// public void PlayEvilLaugh() { currentState = StatueState.EvilLaugh; if (debugMode) Debug.Log("[CrystalStatue] 播放邪恶狞笑"); // 播放狞笑音效 PlayEvilLaughSound(); // 播放狞笑特效 if (evilLaughParticle != null) evilLaughParticle.Play(); // 播放狞笑动画 if (animator != null) animator.SetTrigger(evilLaughAnimTrigger); } /// /// 强制消失(其他雕像) /// public void ForceDisappear(float duration = 0.5f) { canHit = false; // 缩放消失效果 transform.DOScale(Vector3.zero, duration) .SetEase(Ease.InBack) .OnComplete(() => { currentState = StatueState.Broken; gameObject.SetActive(false); }); // 播放碎裂音效 PlayBreakSound(); } #endregion #region 音效播放 private void PlayHitSound() { if (!string.IsNullOrEmpty(hitSound)) { MasterAudio.PlaySound3DAtTransform(hitSound, transform); } } private void PlayBreakSound() { if (!string.IsNullOrEmpty(breakSound)) { MasterAudio.PlaySound3DAtTransform(breakSound, transform); } } private void PlayEvilLaughSound() { if (!string.IsNullOrEmpty(evilLaughSound)) { MasterAudio.PlaySound3DAtTransform(evilLaughSound, transform); } } #endregion #region 视觉效果 private void PlayHitEffect() { if (hitParticle != null) { hitParticle.Play(); } // 播放受击震动效果 PlayHitShake(); } /// /// 播放受击震动效果 /// private void PlayHitShake() { // 使用DOShakePosition实现震动 transform.DOShakePosition( hitShakeDuration, hitShakeStrength, hitShakeVibrato, hitShakeRandomness, false, // 不震Y轴 true // 随机方向 ); // 同时添加轻微的旋转震动 transform.DOShakeRotation( hitShakeDuration, hitShakeStrength * 10f, // 旋转幅度稍大 hitShakeVibrato / 2, hitShakeRandomness, true ); } private void PlayBreakEffect() { if (breakParticle != null) { breakParticle.Play(); } } private void PlayHitAnimation() { if (animator != null) { animator.SetTrigger(hitAnimTrigger); } } private void PlayBreakAnimation() { if (animator != null) { animator.SetTrigger(breakAnimTrigger); } // 碎裂缩放效果 transform.DOScale(Vector3.zero, breakDuration) .SetEase(Ease.InBack) .OnComplete(() => { gameObject.SetActive(false); }); } /// /// 更新裂痕视觉效果 /// private void UpdateCrackVisual(int level) { // 更新裂痕贴花 for (int i = 0; i < crackDecals.Length; i++) { if (crackDecals[i] != null) { crackDecals[i].SetActive(i < level); } } // 更新材质(如果有多个裂痕材质) if (crackMaterials != null && crackMaterials.Length > level && statueRenderer != null) { statueRenderer.material = crackMaterials[level]; } } #endregion #region 工具方法 /// /// 获取当前血量 /// public int GetCurrentHealth() { return currentHealth; } /// /// 获取裂痕等级 /// public int GetCrackLevel() { return crackLevel; } /// /// 是否已碎裂 /// public bool IsBroken() { return currentState == StatueState.Broken; } /// /// 重置雕像状态 /// public void Reset() { currentHealth = maxHealth; crackLevel = 0; canHit = true; currentState = StatueState.Idle; // 重置缩放 transform.localScale = Vector3.one; // 重置裂痕 UpdateCrackVisual(0); // 显示对象 gameObject.SetActive(true); } /// /// 设置可击打状态 /// public void SetCanHit(bool value) { canHit = value; } #endregion #region 编辑器辅助 #if UNITY_EDITOR [ContextMenu("测试:击打雕像")] private void TestHit() { OnPlayerHit(); } [ContextMenu("测试:碎裂雕像")] private void TestBreak() { Break(); } [ContextMenu("测试:播放狞笑")] private void TestEvilLaugh() { PlayEvilLaugh(); } [ContextMenu("测试:重置雕像")] private void TestReset() { Reset(); } [ContextMenu("测试:强制消失")] private void TestForceDisappear() { ForceDisappear(); } #endif #endregion }