上海虹口龙之梦项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

294 lines
8.1 KiB

using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// 摄影机旋转
/// </summary>
public class CameraOrbit : MonoSingleton<CameraOrbit>
{
//目标点
public Transform target;
//x轴旋转速度
public float speedX = 200f;
//y轴旋转速度
public float speedY = 200f;
//滚轮缩放速度
public float speed = 5f;
//y轴限制最小角度
public float minY = 0f;
//y轴限制最大角度
public float maxY = 90f;
//摄影机与目标点距离
public float distance = 100f;
//最小距离
public float minDistance = 0f;
//最大距离
public float maxDistance = 200f;
//是否开启阻尼
public bool isDamping = true;
//阻尼值
private float damping = 5.0f;
//x轴旋转角度
public float x = 0.0f;
//y轴旋转角度
public float y = 0.0f;
//中心
private Vector3 _center;
private Vector3 _prevPos = Vector3.zero;
//初始数据
private float _originalX;
private float _originalY;
private float _originalDistance;
private Vector3 _originalTargetPosition;
private Vector3 _originalCameraPosition;
private Quaternion _originalCameraRotation;
private float _originalSpeed;
//拖拽
public bool isDragEnabled = true;
//目标点移动速度
public float moveSpeed = 10f;
//目标点最小高度
public float minHeight = -10f;
//目标点最大高度
public float maxHeight = 40f;
//自动旋转
public bool isAutoRotate;
//旋转速度
public float RotSpeed = 5f;
private void OnEnable()
{
_center = GetComponent<Camera>().ScreenToWorldPoint(new Vector3(Screen.width / 2, Screen.height / 2, 0));
UIManager.CreateEventSystem();
}
private void Start()
{
var angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
GetOriginalData();
}
private void Update()
{
//滚轮速度控制
SpeedControl();
//Distance微调
DistanceControl();
//摄影机旋转
CameraRotation();
//摄影机拖拽
CameraDrag();
//目标点移动
TargetMoved();
//自动旋转
if (isAutoRotate)
x += Time.deltaTime * RotSpeed;
}
private void LateUpdate()
{
if (Input.GetMouseButton(1))
isAutoRotate = false;
}
#region Private Function
private 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);
}
/// <summary>
/// 滚轮速度控制
/// </summary>
private void SpeedControl()
{
if (distance >= 30f)
speed = distance / 3f;
else
speed = 10f;
if (Input.GetKey(KeyCode.LeftShift))
speed = _originalSpeed;
}
/// <summary>
/// 获取摄影机初始数据
/// </summary>
private void GetOriginalData()
{
var t = this.transform;
_originalCameraPosition = t.position;
_originalCameraRotation = t.rotation;
_originalTargetPosition = target.position;
_originalX = x;
_originalY = y;
_originalDistance = distance;
_originalSpeed = speed;
}
/// <summary>
/// 摄影机旋转
/// </summary>
private void CameraRotation()
{
if (Input.GetMouseButton(1))
{
x += Input.GetAxis("Mouse X") * speedX * 0.02f;
y -= Input.GetAxis("Mouse Y") * speedY * 0.02f;
y = ClampAngle(y, minY, maxY);
}
if (!EventSystem.current.IsPointerOverGameObject())
{
distance -= Input.GetAxis("Mouse ScrollWheel") * speed;
}
if (target)
distance = Mathf.Clamp(distance, minDistance, maxDistance);
var rotation = Quaternion.Euler(y, x, 0.0f);
Vector3 disVector;
Vector3 position;
if (target)
{
disVector = new Vector3(0.0f, 0.0f, -distance);
position = rotation * disVector + target.position;
}
else
{
disVector = new Vector3(0.0f, 0.0f, -Vector3.Distance(transform.position, _center));
position = rotation * disVector + _center;
}
if (isDamping)
{
Transform transform1;
(transform1 = transform).rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * damping);
transform.position = Vector3.Lerp(transform1.position, position, Time.deltaTime * damping);
}
else
{
var transform1 = transform;
transform1.SetPositionAndRotation(position, rotation);
}
}
/// <summary>
/// 摄影机拖拽
/// </summary>
private void CameraDrag()
{
if (!isDragEnabled) return;
if (Input.GetMouseButtonDown(2))
{
var screenSpace = GetComponent<Camera>().WorldToScreenPoint(target.position);
_prevPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
}
if (Input.GetMouseButtonUp(2))
{
_prevPos = Vector3.zero;
}
if (!Input.GetMouseButton(2)) return;
{
if (EventSystem.current.IsPointerOverGameObject()) return;
var position = target.position;
var screenSpace = GetComponent<Camera>().WorldToScreenPoint(position);
var currPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
var prev = GetComponent<Camera>().ScreenToWorldPoint(_prevPos);
var curr = GetComponent<Camera>().ScreenToWorldPoint(currPos);
var offset = curr - prev;
offset.y = 0;
position += -offset;
target.position = position;
_prevPos = currPos;
}
}
/// <summary>
/// 目标点拖拽
/// </summary>
private void TargetMoved()
{
if (EventSystem.current.IsPointerOverGameObject())
return;
if (Input.GetKey(KeyCode.UpArrow))
target.transform.Translate(0, Time.deltaTime * moveSpeed, 0);
else if (Input.GetKey(KeyCode.DownArrow))
target.transform.Translate(0, Time.deltaTime * moveSpeed * -1, 0);
var pos = target.transform.position;
if (pos.y <= minHeight)
target.transform.position = new Vector3(pos.x, minHeight, pos.z);
if (pos.y >= maxHeight)
target.transform.position = new Vector3(pos.x, maxHeight, pos.z);
}
/// <summary>
/// 摄影机与目标点距离微雕快捷键
/// </summary>
private void DistanceControl()
{
if (Input.GetKeyDown(KeyCode.RightBracket)) //]
distance++;
else if (Input.GetKeyDown(KeyCode.LeftBracket)) //[
distance--;
}
#endregion
#region Public Function
/// <summary>
/// 重置摄影机位置
/// </summary>
public void ResetCamera()
{
var transform1 = this.transform;
transform1.position = _originalCameraPosition;
transform1.rotation = _originalCameraRotation;
target.position = _originalTargetPosition;
x = _originalX;
y = _originalY;
distance = _originalDistance;
}
/// <summary>
/// 设置摄影机视角
/// </summary>
/// <param name="targetPos">目标点位置</param>
/// <param name="dis">距离</param>
public void SetCameraView(Vector3 targetPos, float dis)
{
target.transform.position = targetPos;
distance = dis;
}
/// <summary>
/// 视角移动方法
/// </summary>
/// <param name="TargetPos">目标点</param>
/// <param name="CameraDistance">距离</param>
/// <param name="CameraX">横向偏移</param>
/// <param name="CameraY">竖向偏移</param>
public void SetCameraView(Vector3 TargetPos, float CameraDistance, float CameraX, float CameraY)
{
x = CameraX;
y = CameraY;
distance = CameraDistance;
if (target != null)
target.transform.position = TargetPos;
}
#endregion
}