##untiy平移旋转缩放【自用源码】
using DG.Tweening;
using System;
using UnityEngine;
namespace DR.ThreeDimensions
{
public class MouseExhibitionControl : MonoBehaviour
{
//相机跟随的目标物体,一般是一个空物体
[HideInInspector]
public Transform target;
public Vector3 jfcenter;
private float MouseWheelSensitivity = 10; //滚轮灵敏度设置
private float MouseZoomMin = 5; //相机距离最小值
private float MouseZoomMax = 40; //相机距离最大值
private float moveSpeed = 10; //相机跟随速度(中键平移时),采用平滑模式时起作用,越大则运动越平滑
private float xSpeed = 250.0f; //旋转视角时相机x轴转速
private float ySpeed = 120.0f; //旋转视角时相机y轴转速
private int yMinLimit = 10;
private int yMaxLimit = 70;
private float x = 0.0f; //存储相机的euler角
private float y = 0.0f; //存储相机的euler角
private float Distance = 20; //相机和target之间的距离,因为相机的Z轴总是指向target,也就是相机z轴方向上的距离
private Vector3 targetOnScreenPosition; //目标的屏幕坐标,第三个值为z轴距离
private Quaternion storeRotation; //存储相机的姿态四元数
public Vector3 CameraTargetPosition; //target的位置
private Vector3 initPosition; //平移时用于存储平移的起点位置
private Vector3 cameraX; //相机的x轴方向向量
private Vector3 cameraY; //相机的y轴方向向量
private Vector3 cameraZ; //相机的z轴方向向量
private Vector3 initScreenPos; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用)
private Vector3 curScreenPos; //当前鼠标的屏幕坐标(第三个值其实没什么用)
private void SynchronizationData()
{
CameraTargetPosition = target.position;
targetOnScreenPosition = Camera.main.WorldToScreenPoint(CameraTargetPosition);
storeRotation = transform.rotation;
cameraX = transform.right;
cameraY = transform.up;
cameraZ = transform.forward;
Distance = Vector3.Distance(transform.position, target.position);
x = transform.eulerAngles.y;
y = transform.eulerAngles.x;
}
void Start()
{
campass = GameObject.FindGameObjectWithTag("Camera");
GameObject t = GameObject.FindGameObjectWithTag("Target");
if (t) target = t.transform;
else target = GameObject.Find("Target").transform;
jfcenter = target.position;
//这里就是设置一下初始的相机视角以及一些其他变量,这里的x和y。。。是和下面getAxis的mouse x与mouse y对应
SetDistance();
var angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
CameraTargetPosition = target.position;
storeRotation = Quaternion.Euler(y, x, 0);
transform.rotation = storeRotation; //设置相机姿态
Vector3 position = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + CameraTargetPosition; //四元数表示一个旋转,四元数乘以向量相当于把向量旋转对应角度,然后加上目标物体的位置就是相机位置了
transform.position = storeRotation * new Vector3(0, 0, -Distance) + CameraTargetPosition; //设置相机位置
}
float cabinetMaxDis = 3;
private void SetDistance()
{
int topdistance = MessageManager.Instance.GetSetttingValueToInt("topDistance");
if (topdistance > 0)
{
Distance = topdistance;
}
string value = MessageManager.Instance.GetSetttingValue("cabinetMaxDis");
if (!string.IsNullOrEmpty(value))
{
try
{
float dis = float.Parse(value);
if (dis >= 2) { cabinetMaxDis = dis; }
}
catch (System.Exception)
{
}
}
}
void Update()
{
switch (m_type)
{
case ControlType.top:
//鼠标右键旋转功能
RotateFunction();
//鼠标滚轮放大缩小
ZoomInAndOutFunction();
//鼠标中键平移
TranslationFunction();
campass.SetActive(true);
break;
case ControlType.cabinet:
//鼠标滚轮放大缩小
ZoomInAndOutFunction();
//鼠标中键平移
TranslationFunction();
campass.SetActive(false);
break;
case ControlType.device:
//鼠标右键旋转功能
RotateFunction();
//鼠标滚轮放大缩小
ZoomInAndOutFunction();
//鼠标中键平移
TranslationFunction();
campass.SetActive(false);
break;
case ControlType.none:
RotateFunction();
ZoomInAndOutFunction();
TranslationFunction();
campass.SetActive(true);
break;
default:
break;
}
}
public static Action OnMouseButtonDown_2;
private void TranslationFunction()
{
if (Input.GetMouseButtonDown(2))
{
if (OnMouseButtonDown_2 != null) OnMouseButtonDown_2();
cameraX = transform.right;
cameraY = transform.up;
cameraZ = transform.forward;
initScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
Debug.Log("downOnce");
//targetOnScreenPosition.z为目标物体到相机xmidbuttonDownPositiony平面的法线距离
targetOnScreenPosition = Camera.main.WorldToScreenPoint(CameraTargetPosition);
initPosition = CameraTargetPosition;
}
if (Input.GetMouseButton(2))
{
curScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
//0.01这个系数是控制平移的速度,要根据相机和目标物体的distance来灵活选择
target.position = initPosition - 0.01f * ((curScreenPos.x - initScreenPos.x) * cameraX + (curScreenPos.y - initScreenPos.y) * cameraY);
//重新计算位置
Vector3 mPosition = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + target.position;
transform.position = mPosition;
// //用这个会让相机的平移变得更平滑,但是可能在你buttonup时未使相机移动到应到的位置,导致再进行旋转与缩放操作时出现短暂抖动
//transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);
}
if (Input.GetMouseButtonUp(2))
{
Debug.Log("upOnce");
//平移结束把cameraTargetPosition的位置更新一下,不然会影响缩放与旋转功能
CameraTargetPosition = target.position;
}
}
private void RotateFunction()
{
if (Input.GetMouseButton(1))
{
UIManager.Instance.GetWindow<NamePanel>().SetVisible(false);
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
storeRotation = Quaternion.Euler(y, x, 0);
var position = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;
transform.rotation = storeRotation;
transform.position = position;
}
}
private void ZoomInAndOutFunction()
{
if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
{
if (Distance >= MouseZoomMin && Distance <= MouseZoomMax)
{
Distance -= Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity;
}
if (Distance < MouseZoomMin)
{
Distance = MouseZoomMin;
}
if (Distance > MouseZoomMax)
{
Distance = MouseZoomMax;
}
var rotation = transform.rotation;
transform.position = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + CameraTargetPosition;
}
}
//将angle限制在min~max之间
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
void testScreenToWorldPoint()
{
//第三个坐标指的是在相机z轴指向方向上的距离
Vector3 screenPoint = Camera.main.WorldToScreenPoint(CameraTargetPosition);
Debug.Log("ScreenPoint: " + screenPoint);
// var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(1,1,10));
// Debug.Log("worldPosition: "+worldPosition);
}
public ControlType m_type;
private GameObject campass;
/// <summary>
/// 刷新Cam操作脚本参数
/// </summary>
/// <param name="t_Cam">相机位置</param>
/// <param name="t_target">target的位置</param>
/// <param name="type">视角类型</param>
public void RefrashTargetTransform(Vector3 pos, Vector3 rotate, Transform t_target, ControlType type)
{
print("刷新状态" + type);
UIManager.Instance.SetWindowVisiableByType(type);
transform.DOMove(pos, 1f);
Tweener tweener = transform.DORotate(rotate, 1f);
target.position = t_target.position;
target.rotation = t_target.rotation;
tweener.OnComplete(SynchronizationData);
m_type = type;
switch (type)
{
case ControlType.top:
MouseZoomMin = 5;
MouseZoomMax = Distance+20;
yMinLimit = -10;
yMaxLimit = 70;
MouseWheelSensitivity = 10;
break;
case ControlType.cabinet:
MouseZoomMin = 1;
MouseZoomMax = cabinetMaxDis;
yMinLimit = -90;
yMaxLimit = 90;
MouseWheelSensitivity = 1;
break;
case ControlType.device:
MouseZoomMin = 0.4f;
MouseZoomMax = 1;
yMinLimit = -90;
yMaxLimit = 90;
MouseWheelSensitivity = 0.1f;
break;
case ControlType.none:
MouseZoomMin = 5;
MouseZoomMax = 40;
yMinLimit = -10;
yMaxLimit = 70;
MouseWheelSensitivity = 10;
break;
default:
break;
}
}
//点击按钮查看设备背面
//x变化为360倍数
public void ButtonRotate(float finalangle = 360)
{
// float xpos = Input.mousePosition.x;
UIManager.Instance.GetWindow<NamePanel>().SetVisible(false);
float dif = finalangle - (x % 360);
// float axis = dif / (xSpeed * 0.02f);//Input.GetAxis的值为所指定的轴上的位移量,即为当前坐标-上一次坐标值
//强制设置鼠标位置
//SetCursorPos((int)(xpos + axis), (int)y);
storeRotation = Quaternion.Euler(y, x + dif, 0);
var position = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;
transform.rotation = storeRotation;
transform.position = position;
x = x + dif;
}
}
public enum ControlType
{
top,
cabinet,
device,
none
}
}