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
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 |
|
|
|
}
|
|
|