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.
385 lines
10 KiB
385 lines
10 KiB
4 years ago
|
using AX.InputSystem;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
using AX.MessageSystem;
|
||
|
using System;
|
||
|
|
||
|
public enum CameraViewState
|
||
|
{
|
||
|
None,
|
||
|
ThirdPersonView,
|
||
|
PlanView
|
||
|
}
|
||
|
|
||
|
public class CameraManager : MonoBehaviour
|
||
|
{
|
||
|
public Transform target;
|
||
|
public float xSpeed = 200, ySpeed = 200, mSpeed = 50;
|
||
|
public float yMinLimit = 3, yMaxLimit = 90;
|
||
|
public float distance = 15, minDistance = 5, maxDistance = 40;
|
||
|
public float Top = 0.0f;
|
||
|
public float x = 0.0f;
|
||
|
public float y = 0.0f;
|
||
|
public bool needDamping = true;
|
||
|
public float damping = 5.0f;
|
||
|
public Vector3 positionOffset = new Vector3();//Target中心点的偏移量
|
||
|
|
||
|
public CameraViewState viewType;//相机目标是否为人物对象
|
||
|
|
||
|
private Quaternion rotation = new Quaternion();
|
||
|
private Vector3 position = new Vector3();
|
||
|
|
||
|
private float mouseScroll = 0.0f;
|
||
|
|
||
|
private float mouse_X = 0.0f;
|
||
|
private float mouse_Y = 0.0f;
|
||
|
private bool rotateStart;
|
||
|
|
||
|
private Vector3 prevPos = Vector3.zero;//进入拖动过程前(开始拖动)时鼠标在屏幕坐标系中的位置
|
||
|
private Vector3 mousePostion = Vector3.zero;
|
||
|
private bool dragStart;
|
||
|
|
||
|
public float VerticalSpeed = 5.0f;
|
||
|
public float yMax = 5.0f;
|
||
|
private float keyX;
|
||
|
private bool targetMoveing;
|
||
|
public float initialTargetPosY;
|
||
|
|
||
|
private float distanceResult;
|
||
|
private float x_Result;
|
||
|
private float y_Result;
|
||
|
private bool flag;
|
||
|
|
||
|
public delegate void TargetChangeHandler(Transform target);
|
||
|
public event TargetChangeHandler targetChanged;
|
||
|
|
||
|
// Use this for initialization
|
||
|
void Awake()
|
||
|
{
|
||
|
target = GameObject.Find("Target").transform;
|
||
|
|
||
|
Vector3 angles = transform.eulerAngles;
|
||
|
x = angles.y;
|
||
|
y = angles.x;
|
||
|
|
||
|
initialTargetPosY = target.position.y;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Update is called once per frame
|
||
|
void LateUpdate()
|
||
|
{
|
||
|
if (target)
|
||
|
{
|
||
|
if (viewType != CameraViewState.ThirdPersonView)
|
||
|
{
|
||
|
UpdateCameraScale();
|
||
|
|
||
|
if (rotateStart)
|
||
|
UpdateCameraRotation();
|
||
|
else
|
||
|
{
|
||
|
if (flag)
|
||
|
{
|
||
|
x = x_Result;
|
||
|
y = y_Result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (dragStart)
|
||
|
UpdateCameraTargetHorizontalPos();
|
||
|
|
||
|
if (targetMoveing)
|
||
|
UpdateCameraTargetVerticalPos();
|
||
|
|
||
|
UpdateCameraState();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UpdateCameraScale();
|
||
|
|
||
|
if (rotateStart)
|
||
|
UpdateCameraRotation();
|
||
|
else
|
||
|
{
|
||
|
if (flag)
|
||
|
{
|
||
|
x = x_Result;
|
||
|
y = y_Result;
|
||
|
}
|
||
|
}
|
||
|
UpdateCameraState();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 更新鼠标滚动操作传人的数据
|
||
|
/// </summary>
|
||
|
public void UpdateCameraScaleData(float mouseScrollData, float distanceRslt)
|
||
|
{
|
||
|
mouseScroll = mouseScrollData;
|
||
|
distanceResult = distanceRslt;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 更新鼠标右键按住状态下,移动鼠标操作传入的数据
|
||
|
/// </summary>
|
||
|
/// <param name="mouseX"></param>
|
||
|
/// <param name="mouseY"></param>
|
||
|
public void UpdateCameraRotationData(CameraCmdArgs arg)
|
||
|
{
|
||
|
mouse_X = arg.mouseX;
|
||
|
mouse_Y = arg.mouseY;
|
||
|
rotateStart = arg.rotateStart;
|
||
|
|
||
|
if (!rotateStart)
|
||
|
{
|
||
|
flag = true;
|
||
|
x_Result = arg.x;
|
||
|
y_Result = arg.y;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 更新鼠标中键按住状态下,鼠标移动操作开始传入的数据
|
||
|
/// </summary>
|
||
|
public void UpdateDragEnterData(Vector3 mousePos, bool draging)
|
||
|
{
|
||
|
mousePostion = mousePos;
|
||
|
dragStart = draging;
|
||
|
|
||
|
var screenSpace = Camera.main.WorldToScreenPoint(target.position);
|
||
|
prevPos = new Vector3(mousePostion.x, mousePostion.y, screenSpace.z);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 更新鼠标中键按住状态下,鼠标移动操作过程中传入的数据
|
||
|
/// </summary>
|
||
|
/// <param name="mousePos"></param>
|
||
|
public void UpdateDragingData(Vector3 mousePos, bool draging)
|
||
|
{
|
||
|
mousePostion = mousePos;
|
||
|
|
||
|
dragStart = draging;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 更新鼠标中键按住状态下,鼠标移动操作结束传入的数据
|
||
|
/// </summary>
|
||
|
/// <param name="mousePos"></param>
|
||
|
public void UpdateDragExitData(Vector3 mousePos, bool draging)
|
||
|
{
|
||
|
prevPos = mousePos;
|
||
|
|
||
|
dragStart = draging;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 更新按Up,Down键操作传入的数据
|
||
|
/// </summary>
|
||
|
/// <param name="keyAix"></param>
|
||
|
public void UpdateCameraVerticalMoveData(float keyAix, bool moveing)
|
||
|
{
|
||
|
keyX = keyAix;
|
||
|
targetMoveing = moveing;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 缩放,旋转,平移,竖直移动相机后,更新其位置,旋转状态
|
||
|
/// </summary>
|
||
|
private void UpdateCameraState()
|
||
|
{
|
||
|
rotation = Quaternion.Euler(y, x, 0.0f);
|
||
|
Vector3 disVector = new Vector3(0.0f, Top, -distance);
|
||
|
position = rotation * disVector + target.position;
|
||
|
|
||
|
if (needDamping)
|
||
|
{
|
||
|
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * damping);
|
||
|
transform.position = Vector3.Lerp(transform.position, position + positionOffset, Time.deltaTime * damping);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
transform.rotation = rotation;
|
||
|
transform.position = position +positionOffset;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 相机缩放
|
||
|
/// </summary>
|
||
|
private void UpdateCameraScale()
|
||
|
{
|
||
|
distance -= mouseScroll * mSpeed;
|
||
|
distance = Mathf.Clamp(distance, minDistance, maxDistance);
|
||
|
|
||
|
if (mouseScroll == 0 && distanceResult != 0)
|
||
|
{
|
||
|
distance = distanceResult;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 相机旋转
|
||
|
/// </summary>
|
||
|
private void UpdateCameraRotation()
|
||
|
{
|
||
|
x += mouse_X * xSpeed * 0.02f;
|
||
|
y -= mouse_Y * ySpeed * 0.02f;
|
||
|
|
||
|
y = ClampAngle(y, yMinLimit, yMaxLimit);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 相机水平移动
|
||
|
/// </summary>
|
||
|
private void UpdateCameraTargetHorizontalPos()
|
||
|
{
|
||
|
if (mousePostion.x > Screen.width || mousePostion.y > Screen.height)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
var screenSpace = Camera.main.WorldToScreenPoint(target.position);
|
||
|
|
||
|
var currPos = new Vector3(mousePostion.x, mousePostion.y, screenSpace.z);
|
||
|
|
||
|
var prev = Camera.main.ScreenToWorldPoint(prevPos);
|
||
|
var curr = Camera.main.ScreenToWorldPoint(currPos);
|
||
|
|
||
|
var offset = curr - prev;
|
||
|
|
||
|
offset.y = 0;
|
||
|
|
||
|
target.position += -offset;
|
||
|
|
||
|
prevPos = currPos;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 相机竖直移动
|
||
|
/// </summary>
|
||
|
private void UpdateCameraTargetVerticalPos()
|
||
|
{
|
||
|
float targetPosY = target.position.y;
|
||
|
|
||
|
if (targetPosY <= yMax && targetPosY >= initialTargetPosY)
|
||
|
{
|
||
|
if (keyX > 0)
|
||
|
{
|
||
|
target.transform.Translate(0, VerticalSpeed * Time.deltaTime, 0);
|
||
|
}
|
||
|
if (keyX < 0)
|
||
|
{
|
||
|
target.transform.Translate(0, -VerticalSpeed * Time.deltaTime, 0);
|
||
|
}
|
||
|
|
||
|
if (target.transform.position.y > yMax)
|
||
|
{
|
||
|
target.position = new Vector3(target.position.x, yMax, target.position.z);
|
||
|
}
|
||
|
if (target.transform.position.y < initialTargetPosY)
|
||
|
{
|
||
|
target.position = new Vector3(target.position.x, initialTargetPosY, target.position.z);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private 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 OnEnable()
|
||
|
{
|
||
|
MessageDispatcher.AddListener(MessageName.RestCamera.ToString(), RestCamera);
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 脚本禁用时移除监听方法
|
||
|
/// </summary>
|
||
|
private void OnDisable()
|
||
|
{
|
||
|
MessageDispatcher.RemoveListener(MessageName.RestCamera.ToString(), RestCamera);
|
||
|
}
|
||
|
//复位
|
||
|
private void RestCamera(IMessage obj)
|
||
|
{
|
||
|
if (flag)
|
||
|
{
|
||
|
x_Result = 180f;
|
||
|
y_Result = 90f;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
x = 180f;
|
||
|
y = 90f;
|
||
|
}
|
||
|
}
|
||
|
/// <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;
|
||
|
x_Result = CameraX;
|
||
|
y_Result = CameraY;
|
||
|
distanceResult = CameraDistance;
|
||
|
if (target != null)
|
||
|
target.transform.position = TargetPos;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 相机视觉切换
|
||
|
/// </summary>
|
||
|
/// <param name="TargetPos"></param>
|
||
|
/// <param name="CameraDistance"></param>
|
||
|
/// <param name="minDistance"></param>
|
||
|
/// <param name="maxDistance"></param>
|
||
|
public void ChangeCameraView(Vector3 TargetPos, float CameraDistance,float minDis,float maxDis)
|
||
|
{
|
||
|
distance = CameraDistance;
|
||
|
minDistance = minDis;
|
||
|
maxDistance = maxDis;
|
||
|
if (distance > maxDistance)
|
||
|
{
|
||
|
distance = maxDistance;
|
||
|
}
|
||
|
if (distance < minDistance)
|
||
|
{
|
||
|
distance = minDistance;
|
||
|
}
|
||
|
distanceResult = distance;
|
||
|
if (target != null)
|
||
|
{
|
||
|
target.transform.position = TargetPos;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// 更换相机跟随对象
|
||
|
/// </summary>
|
||
|
/// <param name="targetObj"></param>
|
||
|
public void ChangeTarget(GameObject targetObj)
|
||
|
{
|
||
|
target = targetObj.transform;
|
||
|
if (targetChanged != null)
|
||
|
{
|
||
|
targetChanged(target);
|
||
|
}
|
||
|
}
|
||
|
}
|