222 lines
5.3 KiB
C#
Raw Normal View History

2025-06-03 18:25:22 +08:00
using UnityEngine;
2025-07-01 16:37:26 +08:00
using UnityEngine.EventSystems;
2025-06-03 18:25:22 +08:00
public class ZhanShiCameraMove : MonoBehaviour
{
[Header("旋转角度x,y缩放距离distance")] public float x, y, distance;
[Header("X角度设置")] public float minYangle;
public float maxYangle;
[Header("缩放的最小距离")] public float distanceMin;
[Header("缩放的最大距离")] public float distanceMax;
[Header("需要注视的物体")] public Transform target;
public static ZhanShiCameraMove instance;
[Header("缩放的速度")] public float scrollSpeed;
[Header("旋转的速度")] public float rotSpeed;
// Start is called before the first frame update
2025-07-01 16:37:26 +08:00
2025-06-03 18:25:22 +08:00
private void Start()
{
//初始化最开始位置
instance = this;
// transform.LookAt(target);
isAutoRotate = false;
2025-07-01 16:37:26 +08:00
if (isAutoRotate)
{
2025-06-03 18:25:22 +08:00
Invoke("SetBool", 2f);
}
}
/// <summary>
/// 初始状态,延时两秒设置这个参数
/// </summary>
void SetBool()
{
2025-07-01 16:37:26 +08:00
2025-06-03 18:25:22 +08:00
isAutoRotate = true;
}
2025-07-01 16:37:26 +08:00
/// <summary>
/// 更新一下参数
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="distance"></param>
public void SetData(float x, float y, float distance)
{
isAutoRotate = false;
//目标物体旋转置空
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
target.transform.rotation = new Quaternion(0, 0, 0, 0);
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
//相机参数设置
this.x = x;
this.y = y;
this.distance = distance;
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
//根绝XY移动量计算旋转量
this.y = Mathf.Clamp(this.y, minYangle, maxYangle);
Quaternion rot = Quaternion.Euler(this.y, this.x, 0);
transform.rotation = rot;
//对距离进行区间运算,保证距离在最大和最小之间
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
this.distance = Mathf.Clamp(this.distance, distanceMin, distanceMax);
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
//根据距离值计算摄像机的位置
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
Vector3 pos = rot * new Vector3(0, 0, -this.distance) + target.position;
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
//更改摄像机位置为计算的值
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
transform.position = pos;
2025-06-03 18:25:22 +08:00
//延时旋转2秒后
target.transform.localEulerAngles = Vector3.zero;
2025-07-01 16:37:26 +08:00
Invoke("SetBool", 2f);
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
}
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
// Update is called once per frame
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
private void Update()
{
if (isAutoRotate && !Input.GetMouseButton(1))
{
// Debug.Log("测试到鼠标左键没按下");
2025-06-03 18:25:22 +08:00
2025-07-01 16:37:26 +08:00
RotateModelContinuously(); // 持续旋转模型
} // 如果鼠标左键没按下
else
{
2025-06-03 18:25:22 +08:00
//target.transform.rotation = Quaternion.identity;
2025-07-01 16:37:26 +08:00
2025-06-03 18:25:22 +08:00
Drag();
}
2025-07-01 16:37:26 +08:00
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
//根据滚轮的值计算距离
distance = distance - Input.GetAxis("Mouse ScrollWheel") * scrollSpeed;
}
//对距离进行区间运算,保证距离在最大和最小之间
distance = Mathf.Clamp(distance, distanceMin, distanceMax);
//根据距离值计算摄像机的位置
Vector3 pos = transform.rotation * new Vector3(0, 0, -distance) + target.position;
//更改摄像机位置为计算的值
transform.position = pos;
}
void RotateModelContinuously()
{
if (!isAutoRotatePivot)
target.transform.Rotate(autoRotateDirection, autoRotationSpeed * Time.deltaTime * speed, Space.World);
else
2025-06-03 18:25:22 +08:00
{
2025-07-01 16:37:26 +08:00
var rotateEuler = autoRotateDirection * autoRotationSpeed * Time.deltaTime * speed;
// 根据模型当前朝向构造一个围绕轴旋转的四元数
Quaternion deltaRotation = Quaternion.Euler(rotateEuler);
// 将新的旋转应用到模型
target.transform.rotation *= deltaRotation;
2025-06-03 18:25:22 +08:00
}
2025-07-01 16:37:26 +08:00
}
void Drag()
{
if (Input.GetMouseButton(1))
{
//获取鼠标X轴移动量
x = x + Input.GetAxis("Mouse X") * rotSpeed;
//获取鼠标Y轴移动量
y = y - Input.GetAxis("Mouse Y") * rotSpeed;
//如果滚轮发生滚动
2025-06-03 18:25:22 +08:00
}
2025-07-01 16:37:26 +08:00
//根绝XY移动量计算旋转量
y = Mathf.Clamp(y, minYangle, maxYangle);
Quaternion rot = Quaternion.Euler(y, x, 0);
//根据计算的旋转量旋转计算机
transform.rotation = rot;
if (Input.GetAxis("Mouse ScrollWheel") != 0)
2025-06-03 18:25:22 +08:00
{
2025-07-01 16:37:26 +08:00
//根据滚轮的值计算距离
distance = distance - Input.GetAxis("Mouse ScrollWheel") * scrollSpeed;
2025-06-03 18:25:22 +08:00
}
2025-07-01 16:37:26 +08:00
//对距离进行区间运算,保证距离在最大和最小之间
distance = Mathf.Clamp(distance, distanceMin, distanceMax);
//根据距离值计算摄像机的位置
Vector3 pos = rot * new Vector3(0, 0, -distance) + target.position;
//更改摄像机位置为计算的值
transform.position = pos;
2025-06-03 18:25:22 +08:00
}
2025-07-01 16:37:26 +08:00
[SerializeField]
[Header("是否自动旋转")]
private bool isAutoRotate;
[SerializeField]
[Header("是否按照自身坐标系轴自动旋转")]
private bool isAutoRotatePivot;
[SerializeField]
[Header("自动旋转方向,例如(0,1,0)按照Y轴旋转")]
private Vector3 autoRotateDirection;
[SerializeField]
[Header("自动旋转速度")]
private float autoRotationSpeed = 5;
[SerializeField]
[Header("速度")]
private float speed = 5f;
}