ZhangZhouSpecialEquipment/Assets/Scripts/锅炉/GuoLuBaoZhang.cs

372 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class GuoLuBaoZhang : MonoBehaviour
{
public static GuoLuBaoZhang Instance;
//是否开始爆发
public bool IsStartBao = false;
public 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;
public bool IsCanMove = false;
[Header("旋转设置")]
[Tooltip("旋转灵敏度")]
public float rotationSensitivityX = 3f;
public float rotationSensitivityY = 3f;
[Tooltip("垂直旋转限制 - 最小角度")]
public float minVerticalAngle = -60f;
[Tooltip("垂直旋转限制 - 最大角度")]
public float maxVerticalAngle = 60f;
[Tooltip("旋转平滑度")]
public float rotationSmoothness = 10f;
[Header("缩放设置")]
[Tooltip("缩放灵敏度")]
public float scaleSensitivity = 0.1f;
[Tooltip("最小缩放比例")]
public Vector3 minScale = new Vector3(0.5f, 0.5f, 0.5f);
[Tooltip("最大缩放比例")]
public Vector3 maxScale = new Vector3(3f, 3f, 3f);
[Tooltip("缩放平滑度")]
public float scaleSmoothness = 10f;
[Tooltip("重置动画的平滑度")]
public float resetSmoothness = 15f;
// 初始状态变量
private Vector3 initialPosition;
private Quaternion initialRotation;
private Vector3 initialScale;
// 当前目标状态变量
private Vector3 targetScale;
private float currentXRotation;
private float currentYRotation;
private float targetXRotation;
private float targetYRotation;
private Vector3 targetPosition;
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<Animator>();
clip = GetCurrentAnimationClip(animator);
animator.speed = 0;
// 保存初始状态
initialPosition = transform.localPosition;
initialRotation = transform.localRotation;
initialScale = transform.localScale;
// 初始化当前状态为初始状态
targetPosition = initialPosition;
Vector3 initialRotationAngles = initialRotation.eulerAngles;
currentXRotation = targetXRotation = initialRotationAngles.y;
currentYRotation = targetYRotation = initialRotationAngles.x;
targetScale = initialScale;
}
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);
}
}
}
void LateUpdate()
{
// 处理旋转和缩放输入
if (IsCanMove) // 重置时忽略其他输入
{
HandleRotationInput();
HandleScaleInput();
}
// 应用平滑变换
ApplySmoothRotation();
ApplySmoothScaling();
ApplySmoothPosition();
}
/// <summary>
/// 重置物体到初始状态(位置、旋转、缩放)
/// </summary>
public void ResetToInitialState()
{
// 设置目标状态为初始状态
targetPosition = initialPosition;
targetScale = initialScale;
Vector3 initialRotationAngles = initialRotation.eulerAngles;
targetXRotation = initialRotationAngles.y;
targetYRotation = initialRotationAngles.x;
}
void HandleRotationInput()
{
// 当按住指定的鼠标按钮时处理旋转
if (Input.GetMouseButton(1))
{
float mouseX = Input.GetAxis("Mouse X") * rotationSensitivityX;
float mouseY = Input.GetAxis("Mouse Y") * rotationSensitivityY;
targetXRotation += mouseX;
targetYRotation -= mouseY;
// 限制垂直旋转角度
targetYRotation = Mathf.Clamp(targetYRotation, minVerticalAngle, maxVerticalAngle);
}
}
void HandleScaleInput()
{
//if (useMouseWheelForScale)
//{
float scrollInput = Input.GetAxis("Mouse ScrollWheel");
if (scrollInput != 0)
{
Vector3 scaleChange = Vector3.one * (scrollInput > 0 ? 1 : -1) * scaleSensitivity;
Vector3 newScale = targetScale + scaleChange;
targetScale = new Vector3(
Mathf.Clamp(newScale.x, minScale.x, maxScale.x),
Mathf.Clamp(newScale.y, minScale.y, maxScale.y),
Mathf.Clamp(newScale.z, minScale.z, maxScale.z)
);
}
//}
//else
//{
// // 备选方案:使用左右键同时按下缩放(如果不使用滚轮)
// if (Input.GetMouseButton(0) && Input.GetMouseButton(1))
// {
// float mouseY = Input.GetAxis("Mouse Y") * scaleSensitivity;
// Vector3 newScale = targetScale + Vector3.one * (mouseY > 0 ? 1 : -1) * scaleSensitivity;
// targetScale = new Vector3(
// Mathf.Clamp(newScale.x, minScale.x, maxScale.x),
// Mathf.Clamp(newScale.y, minScale.y, maxScale.y),
// Mathf.Clamp(newScale.z, minScale.z, maxScale.z)
// );
// }
//}
}
void ApplySmoothRotation()
{
currentXRotation = Mathf.Lerp(currentXRotation, targetXRotation,
rotationSmoothness * Time.deltaTime);
currentYRotation = Mathf.Lerp(currentYRotation, targetYRotation,
rotationSmoothness * Time.deltaTime);
transform.rotation = Quaternion.Euler(currentYRotation, currentXRotation, 0);
}
void ApplySmoothScaling()
{
transform.localScale = Vector3.Lerp(
transform.localScale,
targetScale,
scaleSmoothness * Time.deltaTime
);
}
void ApplySmoothPosition()
{
// 处理位置平滑过渡(主要用于重置时)
transform.localPosition = Vector3.Lerp(
transform.localPosition,
targetPosition,
resetSmoothness * Time.deltaTime
);
}
/// <summary>
/// 动画开始正常播放
/// </summary>
public void StartPlayAnim()
{
if (animator != null)
{
IsStartBao = true;
animator.Play(clip.name, -1, explosionFactor);
animator.speed = 1;
}
}
/// <summary>
/// 动画结束
/// </summary>
public void EndPlayAnim()
{
if (animator != null)
{
IsStartBao = false;
}
}
/// <summary>
/// 让当前动画跳转到指定时间(秒)
/// </summary>
/// <param name="timepercent">目标时间比</param>
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;
}
/// <summary>
/// 获取当前层正在播放的AnimationClip
/// </summary>
private AnimationClip GetCurrentAnimationClip(Animator anim)
{
AnimationClip[] animationClips = anim.runtimeAnimatorController.animationClips;
return animationClips[0];
}
/// <summary>
/// 当滑动条值改变时调用(实时控制)
/// </summary>
public void OnSliderValueChanged(float value)
{
m_isSliderChange = true;
UpdateCanvasState();
}
/// <summary>
/// 控制 Canvas 显示/隐藏与浮动
/// </summary>
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<TextMeshProUGUI>();
if (name != null)
name.text = CanvasObj.name;
// 上下浮动动画
Vector3 pos = CanvasObj.transform.position;
if (shouldShow)
CanvasObj.transform.position = new Vector3(pos.x, pos.y + 0.8f, pos.z);
else
CanvasObj.transform.position = new Vector3(pos.x, pos.y - 0.8f, pos.z);
}
}
}
}