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.
495 lines
15 KiB
495 lines
15 KiB
using AX.InputSystem; |
|
using AX.MessageSystem; |
|
using System; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
using UnityEngine; |
|
|
|
[Serializable] |
|
public class CameraData |
|
{ |
|
public Vector3 targetPos; |
|
public float x; |
|
public float y; |
|
public float distance; |
|
|
|
} |
|
[Serializable] |
|
public class CameraReplayData |
|
{ |
|
public Vector3 myPostion; |
|
public Quaternion myRotation; |
|
public float myTime; |
|
} |
|
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; |
|
|
|
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; |
|
private float recordtimmer; |
|
private float recordtime; |
|
private float lastrecordtime; |
|
private CameraReplayData data; |
|
private CameraReplayData rePlaydata; |
|
private bool isReplay = false; |
|
private bool isReplayData = false; |
|
private float rePlaytimmer; |
|
private ReplayManager replayManager; |
|
private Vector3 startPos; |
|
private Quaternion startRot; |
|
private Quaternion stopQuaternion; |
|
private Vector3 stopTransform; |
|
private bool canUpDate; |
|
|
|
// 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; |
|
MessageDispatcher.AddListener("ReplayFrame", ReplayFrameCamera); |
|
MessageDispatcher.AddListener("ReplayEvent", ReplayCamera); |
|
data = new CameraReplayData(); |
|
replayManager = GameObject.Find("Canvas").transform.Find("TopUI/TimeLinePanel").GetComponent<ReplayManager>(); |
|
MessageDispatcher.AddListener("ReplayStatusChanged", RePlayStusChanged); |
|
CameraData cdata = new CameraData//初始化视角 |
|
{ |
|
//x = 180f, |
|
//y = 30f, |
|
//distance = 95f, |
|
x = -45f, |
|
y = 18f, |
|
distance = 90f, |
|
// targetPos = new Vector3(-180.7f, 1.02f, -40f) |
|
targetPos = new Vector3(118f, 10f, -64f) |
|
}; |
|
CameraSetting(cdata); |
|
} |
|
|
|
|
|
|
|
private void ReplayCamera(IMessage obj) |
|
{ |
|
var eventData = (EventData)obj.Data; |
|
if (eventData.eventType == RecordEventType.Camera) |
|
{ |
|
rePlaydata = JsonUtility.FromJson<CameraReplayData>(eventData.json); |
|
isReplay = true; |
|
isReplayData = true; |
|
//记录回放开始点状态 |
|
rePlaytimmer = replayManager.replayTime; |
|
startPos = transform.position; |
|
startRot = transform.rotation; |
|
} |
|
} |
|
|
|
private void OnDestroy() |
|
{ |
|
MessageDispatcher.RemoveListener("ReplayFrame", ReplayFrameCamera); |
|
MessageDispatcher.RemoveListener("ReplayEvent", ReplayCamera); |
|
MessageDispatcher.RemoveListener("ReplayStatusChanged", RePlayStusChanged); |
|
} |
|
|
|
private void ReplayFrameCamera(IMessage obj) |
|
{ |
|
var objectData = (ObjectData)obj.Data; |
|
if (objectData.cloneObjType == CloneObjType.Camera) |
|
{ |
|
CameraData data = JsonUtility.FromJson<CameraData>(objectData.json); |
|
CameraSetting(data); |
|
} |
|
} |
|
public CameraData GetNowCameraData() |
|
{ |
|
CameraData data = new CameraData() |
|
{ |
|
x = this.x, |
|
y = this.y, |
|
distance = this.distance, |
|
targetPos = target.position |
|
}; |
|
return data; |
|
} |
|
public void CameraSetting(CameraData data) |
|
{ |
|
if (target != null) |
|
target.transform.position = data.targetPos; |
|
this.x = data.x; |
|
this.y = data.y; |
|
this.distance = data.distance; |
|
x_Result = data.x; |
|
y_Result = data.y; |
|
distanceResult = data.distance; |
|
isReplayData = false; |
|
if (replayManager.auto.isOn) |
|
{ |
|
if (isReplay) |
|
isReplay = false; |
|
if (!canUpDate) |
|
canUpDate = true; |
|
} |
|
} |
|
public void CameraFollowTarget(Vector3 targetPos, float distance) |
|
{ |
|
if (ReplaySetting.PlayStatus != PlayStatus.isReplay) |
|
{ |
|
if (target != null) |
|
target.transform.position = targetPos; |
|
distanceResult = distance; |
|
} |
|
if (ReplaySetting.PlayStatus == PlayStatus.isEditor && RecordManager.Instance.recordStatus == RecordStatus.normal) |
|
{ |
|
StopCoroutine(AddFollow()); |
|
StartCoroutine(AddFollow()); |
|
} |
|
//if (ReplaySetting.PlayStatus == PlayStatus.isEditor && RecordManager.Instance.recordStatus == RecordStatus.normal) |
|
//{ |
|
// AddRecordCamera(RecordManager.Instance.RecordTimer, 0.2f); |
|
//} |
|
} |
|
IEnumerator AddFollow() |
|
{ |
|
var starttime = RecordManager.Instance.RecordTimer; |
|
yield return new WaitForSeconds(0.1f); |
|
AddRecordCamera(starttime, 0.2f); |
|
} |
|
private void RePlayStusChanged(IMessage obj) |
|
{ |
|
ReplayStatus lastStatus = (ReplayStatus)obj.Data; |
|
if (lastStatus == ReplayStatus.normal)//从暂停切换到播放状态 |
|
{ |
|
if (!isReplay) |
|
{ |
|
isReplay = true; |
|
if (stopTransform != Vector3.zero) |
|
{ |
|
transform.position = stopTransform;//重新赋值到暂停时相机的参数 |
|
transform.rotation = stopQuaternion; |
|
} |
|
} |
|
} |
|
else if (lastStatus == ReplayStatus.pause)//从播放切换到暂停状态 |
|
{ |
|
if (isReplay) |
|
{ |
|
isReplay = false; |
|
stopTransform = transform.position;//记录播放暂停相机状态参数 |
|
stopQuaternion = transform.rotation; |
|
|
|
canUpDate = false; |
|
if (!replayManager.auto.isOn) |
|
{ |
|
//还原相机参数 |
|
Vector3 angles = transform.eulerAngles; |
|
x = angles.y; |
|
y = angles.x; |
|
target.transform.position = transform.position - transform.rotation * new Vector3(0, Top, -distance); |
|
target.transform.position = new Vector3(target.position.x, initialTargetPosY, target.position.z); |
|
//canUpDate = true; |
|
} |
|
} |
|
} |
|
else//结束状态回放结束 |
|
{ |
|
if (isReplay) |
|
isReplay = false; |
|
} |
|
} |
|
// Update is called once per frame |
|
void LateUpdate() |
|
{ |
|
//if (isObservePerson) |
|
//{ |
|
// transform.rotation = Quaternion.Lerp(target.transform.rotation, rotation, Time.deltaTime * damping); ; |
|
// transform.position = Vector3.Lerp(target.transform.position, position + positionOffset, Time.deltaTime * damping); |
|
//} |
|
if (target) |
|
{ |
|
if (!isReplay && canUpDate) |
|
{ |
|
UpdateCameraScale(); |
|
|
|
if (rotateStart) |
|
UpdateCameraRotation(); |
|
else |
|
{ |
|
if (flag) |
|
{ |
|
x = x_Result; |
|
y = y_Result; |
|
} |
|
} |
|
|
|
if (dragStart) |
|
UpdateCameraTargetHorizontalPos(); |
|
|
|
if (targetMoveing) |
|
UpdateCameraTargetVerticalPos(); |
|
|
|
UpdateCameraState(); |
|
} |
|
else |
|
{ |
|
if (isReplayData) |
|
{ |
|
//rePlaytimmer += (Time.smoothDeltaTime * ReplayManager.playSpeed); |
|
//Debug.Log(rePlaydata.myTime + ":" + rePlaytimmer); |
|
if (transform.position != rePlaydata.myPostion) |
|
{ |
|
transform.position = Vector3.Lerp(startPos, rePlaydata.myPostion, (replayManager.replayTime - rePlaytimmer) / rePlaydata.myTime); |
|
} |
|
if (transform.rotation != rePlaydata.myRotation) |
|
{ |
|
transform.rotation = Quaternion.Lerp(startRot, rePlaydata.myRotation, (replayManager.replayTime - rePlaytimmer) / rePlaydata.myTime); |
|
} |
|
if ((replayManager.replayTime - rePlaytimmer) >= rePlaydata.myTime) |
|
{ |
|
transform.position = rePlaydata.myPostion; |
|
transform.rotation = rePlaydata.myRotation; |
|
isReplayData = false; |
|
rePlaytimmer = 0; |
|
} |
|
} |
|
else |
|
{ |
|
if (ReplaySetting.PlayStatus != PlayStatus.isReplay) |
|
{ |
|
isReplay = false; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
public void AddRecordCamera(float startTime, float timeSpan) |
|
{ |
|
var eventData = new EventData(); |
|
eventData.time = startTime; |
|
eventData.cloneObjType = CloneObjType.None; |
|
eventData.eventType = RecordEventType.Camera; |
|
data.myRotation = Quaternion.Euler(y, x, 0.0f); |
|
Vector3 disVector = new Vector3(0.0f, Top, -distance); |
|
data.myPostion = data.myRotation * disVector + target.position; |
|
data.myTime = timeSpan; |
|
eventData.json = JsonUtility.ToJson(data); |
|
|
|
RecordManager.Instance.jsonData.eventDataList.Add(eventData); |
|
} |
|
/// <summary> |
|
/// 更新鼠标滚动操作传人的数据 |
|
/// </summary> |
|
public void UpdateCameraScaleData(float mouseScrollData, float distanceRslt) |
|
{ |
|
mouseScroll = mouseScrollData; |
|
distanceResult = distanceRslt; |
|
canUpDate = true; |
|
} |
|
|
|
/// <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; |
|
} |
|
canUpDate = true; |
|
} |
|
|
|
/// <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); |
|
canUpDate = true; |
|
} |
|
|
|
/// <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; |
|
canUpDate = true; |
|
} |
|
|
|
/// <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, Time.deltaTime * damping); |
|
} |
|
else |
|
{ |
|
transform.rotation = rotation; |
|
transform.position = position; |
|
} |
|
} |
|
|
|
/// <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); |
|
} |
|
}
|
|
|