186 lines
4.8 KiB
C#
186 lines
4.8 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
public class SeeModelManager : MonoBehaviour
|
||
{
|
||
[Header("目标模型")]
|
||
public Transform targetModel; // 要旋转的模型
|
||
|
||
[Header("相机设置")]
|
||
public Camera mainCamera; // 主相机
|
||
public float minDistance = 1f; // 相机最近距离
|
||
public float maxDistance = 10f; // 相机最远距离
|
||
|
||
[Header("控制参数")]
|
||
public float rotationSpeedX = 2f; // 旋转速度
|
||
public float rotationSpeedY = 2f; // 旋转速度
|
||
|
||
public float zoomSpeed = 1f; // 缩放速度
|
||
|
||
private Vector3 cameraOffset; // 相机与模型的初始偏移
|
||
|
||
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;
|
||
|
||
void Start()
|
||
{
|
||
clip = GetCurrentAnimationClip(animator);
|
||
animator.speed = 0;
|
||
|
||
|
||
if (targetModel == null)
|
||
{
|
||
Debug.LogError("请赋值目标模型(targetModel)!");
|
||
return;
|
||
}
|
||
|
||
if (mainCamera == null)
|
||
{
|
||
mainCamera = Camera.main; // 自动获取主相机
|
||
}
|
||
|
||
// 记录相机与模型的初始偏移(用于缩放时保持方向)
|
||
cameraOffset = mainCamera.transform.position - targetModel.position;
|
||
// 确保相机初始看向模型
|
||
//mainCamera.transform.LookAt(targetModel.position);
|
||
}
|
||
|
||
private AnimationClip GetCurrentAnimationClip(object animator)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
|
||
if (Input.GetMouseButton(0))
|
||
{
|
||
if (m_isSliderChange)
|
||
{
|
||
m_isPlayChange = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_isSliderChange = false;
|
||
}
|
||
|
||
if (Input.GetMouseButtonUp(0) && m_isPlayChange)
|
||
{
|
||
m_isPlayChange = false;
|
||
}
|
||
|
||
|
||
//有手动介入的情况下,模型动画跟随进度条数值改变
|
||
if (explosionFactor != explosionSlider.value)
|
||
{
|
||
explosionFactor = explosionSlider.value;
|
||
JumpToTime(explosionFactor);
|
||
}
|
||
|
||
|
||
// 鼠标左键拖拽控制旋转
|
||
if (Input.GetMouseButton(1))
|
||
{
|
||
RotateModel();
|
||
}
|
||
|
||
// 鼠标滚轮控制缩放(调整相机距离)
|
||
float scroll = Input.GetAxis("Mouse ScrollWheel");
|
||
if (scroll != 0)
|
||
{
|
||
ZoomCamera(scroll);
|
||
}
|
||
}
|
||
|
||
|
||
/// <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>
|
||
/// 当滑动条值改变时调用(实时控制)
|
||
/// </summary>
|
||
public void OnSliderValueChanged(float value)
|
||
{
|
||
m_isSliderChange = true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前层正在播放的AnimationClip
|
||
/// </summary>
|
||
private AnimationClip GetCurrentAnimationClip(Animator anim)
|
||
{
|
||
AnimationClip[] animationClips = anim.runtimeAnimatorController.animationClips;
|
||
|
||
return animationClips[0];
|
||
}
|
||
|
||
|
||
// 旋转模型
|
||
void RotateModel()
|
||
{
|
||
// 获取鼠标在X、Y方向的拖动距离
|
||
float mouseX = Input.GetAxis("Mouse X") * rotationSpeedX;
|
||
float mouseY = Input.GetAxis("Mouse Y") * rotationSpeedY;
|
||
|
||
// 绕Y轴(世界空间)旋转(左右拖动)
|
||
targetModel.Rotate(Vector3.up, mouseX, Space.World);
|
||
// 绕X轴(自身空间)旋转(上下拖动),负号用于修正方向
|
||
targetModel.Rotate(Vector3.right, -mouseY, Space.Self);
|
||
}
|
||
|
||
// 缩放相机(调整与模型的距离)
|
||
void ZoomCamera(float scroll)
|
||
{
|
||
// 计算新的相机位置(沿初始偏移方向调整距离)
|
||
Vector3 newPosition = mainCamera.transform.position +
|
||
mainCamera.transform.forward * scroll * zoomSpeed * -10; // *-10放大滚轮敏感度
|
||
|
||
// 限制相机与模型的距离在min和max之间
|
||
float distance = Vector3.Distance(newPosition, targetModel.position);
|
||
if (distance >= minDistance && distance <= maxDistance)
|
||
{
|
||
mainCamera.transform.position = newPosition;
|
||
}
|
||
}
|
||
}
|