using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.UI; public class FuTiBaoZhang : MonoBehaviour { public static FuTiBaoZhang Instance; //是否开始爆发 public bool IsStartBao = false; private Animator animator; private AnimationClip clip; [Header("UI 控制")] public Slider explosionSlider; // 当前爆炸程度 (0~1) [Range(0, 1)] public float explosionFactor = 0f; //是否手动介入 private bool m_isPlayChange=false; private bool m_isSliderChange = false; public float HuanYuanSpeed = 0f; [Header("Canvas 管理")] public GameObject[] AllCanvas; private void Awake() { Instance = this; foreach (GameObject CanvasObj in AllCanvas) CanvasObj.SetActive(false); // 注册滑动条事件 if (explosionSlider != null) explosionSlider.onValueChanged.AddListener(OnSliderValueChanged); } void Start() { // 获取Animator组件(确保挂载在目标物体上) animator = GetComponent(); clip= GetCurrentAnimationClip(animator); animator.speed = 0; } private void Update() { if(IsStartBao) { if (Input.GetMouseButton(0)) { if (m_isSliderChange) { m_isPlayChange = true; } } else { m_isSliderChange= false; } if (Input.GetMouseButtonUp(0) && m_isPlayChange) { m_isPlayChange = false; } //在没有手动介入的情况下,进度条数值跟随模型动画改变 if (!m_isPlayChange) { // 获取当前动画状态信息 AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); float animtime= Mathf.Clamp(stateInfo.normalizedTime, 0, 1); // 获取当前动画的归一化时间,即已播放百分比 if (explosionFactor!= animtime) { explosionFactor = animtime; explosionSlider.value = explosionFactor; } } else { //有手动介入的情况下,模型动画跟随进度条数值改变 if(explosionFactor != explosionSlider.value) { explosionFactor = explosionSlider.value; JumpToTime(explosionFactor); } } } else { if(explosionFactor>0) { explosionFactor -= HuanYuanSpeed; explosionSlider.value = explosionFactor; JumpToTime(explosionFactor); } } } /// /// 动画开始正常播放 /// public void StartPlayAnim() { if (animator != null) { IsStartBao = true; animator.Play(clip.name, -1, explosionFactor); animator.speed = 1; } } /// /// 动画结束 /// public void EndPlayAnim() { if(animator != null) { IsStartBao=false; } } /// /// 让当前动画跳转到指定时间(秒) /// /// 目标时间比 public void JumpToTime(float timepercent) { if (animator == null) return; if (clip == null) { Debug.LogError("未找到当前播放的动画片段!"); return; } // 2. 检查目标时间是否在动画长度范围内(循环动画可忽略) if (timepercent < 0 || timepercent > 1) { Debug.LogWarning("目标时间超出动画长度!"); timepercent = Mathf.Clamp(timepercent, 0, 1); } // 3. 跳转到目标时间(通过Play方法强制设置归一化时间) // 注意:需传入当前动画状态的名称(或哈希值),确保精准控制 animator.Play(clip.name, -1, timepercent); // 可选:若需要暂停在目标时间,可设置speed为0 animator.speed = 0; } /// /// 获取当前层正在播放的AnimationClip /// private AnimationClip GetCurrentAnimationClip(Animator anim) { AnimationClip[] animationClips = anim.runtimeAnimatorController.animationClips; return animationClips[0]; } /// /// 当滑动条值改变时调用(实时控制) /// public void OnSliderValueChanged(float value) { m_isSliderChange = true; UpdateCanvasState(); } /// /// 控制 Canvas 显示/隐藏与浮动 /// private void UpdateCanvasState() { // 当爆炸程度大于 0.8 时显示 Canvas,否则隐藏 bool shouldShow = explosionFactor > 0.8f; foreach (GameObject CanvasObj in AllCanvas) { if (CanvasObj.activeSelf != shouldShow) { CanvasObj.SetActive(shouldShow); TextMeshProUGUI name = CanvasObj.GetComponentInChildren(); if (name != null) name.text = CanvasObj.name; // 上下浮动动画 Vector3 pos = CanvasObj.transform.position; if (shouldShow) CanvasObj.transform.position = new Vector3(pos.x, pos.y + 10, pos.z); else CanvasObj.transform.position = new Vector3(pos.x, pos.y - 10, pos.z); } } } }