上海杨浦大连路地铁站单机版电子沙盘
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.

496 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);
}
}