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(); 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(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(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); } /// /// 更新鼠标滚动操作传人的数据 /// public void UpdateCameraScaleData(float mouseScrollData, float distanceRslt) { mouseScroll = mouseScrollData; distanceResult = distanceRslt; canUpDate = true; } /// /// 更新鼠标右键按住状态下,移动鼠标操作传入的数据 /// /// /// 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; } /// /// 更新鼠标中键按住状态下,鼠标移动操作开始传入的数据 /// 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; } /// /// 更新鼠标中键按住状态下,鼠标移动操作过程中传入的数据 /// /// public void UpdateDragingData(Vector3 mousePos, bool draging) { mousePostion = mousePos; dragStart = draging; } /// /// 更新鼠标中键按住状态下,鼠标移动操作结束传入的数据 /// /// public void UpdateDragExitData(Vector3 mousePos, bool draging) { prevPos = mousePos; dragStart = draging; } /// /// 更新按Up,Down键操作传入的数据 /// /// public void UpdateCameraVerticalMoveData(float keyAix, bool moveing) { keyX = keyAix; targetMoveing = moveing; canUpDate = true; } /// /// 缩放,旋转,平移,竖直移动相机后,更新其位置,旋转状态 /// 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; } } /// /// 相机缩放 /// private void UpdateCameraScale() { distance -= mouseScroll * mSpeed; distance = Mathf.Clamp(distance, minDistance, maxDistance); if (mouseScroll == 0 && distanceResult != 0) { distance = distanceResult; } } /// /// 相机旋转 /// private void UpdateCameraRotation() { x += mouse_X * xSpeed * 0.02f; y -= mouse_Y * ySpeed * 0.02f; y = ClampAngle(y, yMinLimit, yMaxLimit); } /// /// 相机水平移动 /// 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; } /// /// 相机竖直移动 /// 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); } }