ElectricityBusinessHall_Dig.../Assets/Res/Scripts/Manager/CameraManager.cs

362 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Cinemachine;
using DG.Tweening;
using HXSJFrameWork;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
public class CameraManager : MonoBehaviour
{
public static CameraManager _instance;
public Camera mainCam;//主相机
public Camera singleCam;//单体化展示相机
public GameObject curentSingleObj;//当前单体化的模型
//第一人称巡查
public CinemachineDollyCart firstcart;
public CinemachineSmoothPath firstPath; //第一人称巡查
public CinemachineDollyCart globalcart;
public List<CinemachineSmoothPath> globalpaths; //上帝视角巡查
public bool isInFirstRoam;//是否在第一人称漫游中
private float _roamSpeed = 1.5f;//巡查速度
private float camMoveSpeed = 10;//相机切换视角时的移动速度
private Vector3 camInitPos;//相机初始位置
private Vector3 camInitAngle;//相机初始角度
//待机时长
private float waitTime = 18;
Tweener t_camAnimAngle;//相机转动动画
Tweener t_camAnimPos;//相机移动动画
private void Awake()
{
_instance = this;
}
// Start is called before the first frame update
void Start()
{
camInitPos = mainCam.transform.position;
camInitAngle = mainCam.transform.eulerAngles;
}
private float UnFocusTime = 0;
//是否开始检测鼠标状态
private bool isStartCheck;
//是否在漫游过程中
private bool isInRoam;
// Update is called once per frame
void Update()
{
//if (Input.GetKeyDown(KeyCode.O))
//{
// GlobalRoam(true);
//}
//if (Input.GetKeyDown(KeyCode.P))
//{
// GlobalRoam(false);
//}
//return;
//处于第一人称漫游和不在第一个模块时,不计算待机时长
if (isInFirstRoam || MainUIManager._instance.curModuleIndex != 0)
return;
//鼠标有动静,清空计算无动静时长
if (Input.anyKey || Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0)
{
UnFocusTime = 0;
isStartCheck = true;
if (isInRoam)
{
Debug.Log("停止漫游");
isInRoam = false;
GlobalRoam(false);
}
}
if (isStartCheck)
{
//鼠标长时间未动,自动进入漫游
UnFocusTime += Time.deltaTime;
if (UnFocusTime > waitTime)
{
UnFocusTime = 0;
Debug.Log("长时间未动鼠标!");
isStartCheck = false;
isInRoam = true;
GlobalRoam(true);
}
}
}
/// <summary>
/// 回到初始视角
/// </summary>
public void InitView(Action call = null)
{
CameraMoveTarget(camInitPos, Quaternion.Euler(camInitAngle), () => {
if (call != null)
call();
});
}
/// <summary>
/// 第一人称漫游
/// </summary>
/// <param name="args">true:开始巡查false:结束巡查</param>
public void FirstAutoRoam(bool isRoam)
{
if (isRoam)
{
isInFirstRoam = true;
//从头开始
firstcart.m_Position = 0;
firstcart.m_Speed = 0.01f;
CameraStartRoam(firstcart.transform.position, Quaternion.Euler(firstcart.transform.eulerAngles), ()=>{
mainCam.GetComponent<ModelViewer>()._enabled = false;
firstcart.m_Speed = _roamSpeed;
mainCam.transform.parent = firstcart.transform;
mainCam.transform.localPosition = Vector3.zero;
mainCam.transform.localEulerAngles = Vector3.zero;
});
}
else
{
firstcart.m_Speed = 0;
mainCam.transform.parent = transform;
isInFirstRoam = false;
//回到初始视角
CameraMoveTarget(camInitPos, Quaternion.Euler(camInitAngle));
}
}
//全局漫游协程
Coroutine i_globalroam;
/// <summary>
/// 长时间不动鼠标,全局俯视漫游
/// </summary>
public void GlobalRoam(bool start)
{
if (start)
{
//开始全局漫游
i_globalroam = StartCoroutine(StartGlobalRoam());
}
else {
//停止全局漫游
StopCoroutine(i_globalroam);
StopGlobalRoam();
}
}
/// <summary>
/// 循环楼层
/// </summary>
/// <returns></returns>
public IEnumerator StartGlobalRoam()
{
//(从零开始)
int index = -1;
while (true)
{
index++;
index = index % MainUIManager._instance.buildFloorCount;
//根据索引选择路径漫游
//globalcart.m_Path = globalpaths[index];
StartGlobalRoam(globalpaths[index]);
//根据索引隐藏模型
MainUIManager._instance.ChangeFloor(index + 1);
//第一次结束
Debug.Log("全局漫游索引"+index);
Debug.Log(globalpaths[index].name +"长度"+ globalpaths[index].PathLength);
Debug.Log("时间" + (globalpaths[index].PathLength / _roamSpeed));
yield return new WaitForSeconds(globalpaths[index].PathLength / _roamSpeed);
}
}
/// <summary>
/// 开始全局漫游(其中一层)
/// </summary>
/// <param name="cart">漫游路线</param>
public void StartGlobalRoam(CinemachineSmoothPath path)
{
if (t_camAnimAngle != null)
t_camAnimAngle.Kill();
if (t_camAnimPos != null)
t_camAnimPos.Kill();
globalcart.m_Path = path;
globalcart.m_Position = 0;
globalcart.m_Speed = 0.01f;
CameraStartRoam(globalcart.transform.position, Quaternion.Euler(globalcart.transform.eulerAngles.x + 75f, globalcart.transform.eulerAngles.y, globalcart.transform.eulerAngles.z), () =>
{
mainCam.GetComponent<ModelViewer>()._enabled = false;
globalcart.m_Speed = _roamSpeed;
mainCam.transform.parent = globalcart.transform;
mainCam.transform.localPosition = Vector3.zero;
mainCam.transform.localEulerAngles = new Vector3(75f, 0, 0);
});
}
/// <summary>
/// 停止全局漫游
/// </summary>
private void StopGlobalRoam()
{
globalcart.m_Speed = 0;
mainCam.transform.parent = transform;
//恢复观察楼层
MainUIManager._instance.ChangeFloor(MainUIManager._instance.curfloor);
//回到默认视角
InitView();
}
/// <summary>
/// 相机开始漫游,移动到漫游处,相机不可操作
/// </summary>
/// <param name="endPos"></param>
/// <param name="endAngle"></param>
/// <param name="call"></param>
public void CameraStartRoam(Vector3 endPos, Quaternion endAngle, Action call = null)
{
if (t_camAnimAngle != null)
t_camAnimAngle.Kill();
if (t_camAnimPos != null)
t_camAnimPos.Kill();
mainCam.GetComponent<ModelViewer>()._enabled = false;
float dis = float.Parse((mainCam.transform.position - endPos).magnitude.ToString("f3"));
//Debug.Log(dis+"@@@@@@");
float time = dis / camMoveSpeed;
t_camAnimPos = mainCam.transform.DOMove(endPos, time);
t_camAnimAngle = mainCam.transform.DORotate(endAngle.eulerAngles, time).OnComplete(() => {
if (call != null)
call();
});
}
/// <summary>
/// 相机直接移到目标位置(点击设备、人物等移动视角)
/// </summary>
/// <param name="endPos">相机终点位置</param>
/// <param name="endAngle">相机终点角度</param>
public void CameraMoveTarget(Vector3 endPos, Quaternion endAngle, Action call = null)
{
if (t_camAnimAngle != null)
t_camAnimAngle.Kill();
if (t_camAnimPos != null)
t_camAnimPos.Kill();
mainCam.GetComponent<ModelViewer>()._enabled = false;
float dis = float.Parse((mainCam.transform.position - endPos).magnitude.ToString("f3"));
//Debug.Log(dis+"@@@@@@");
float time = dis / camMoveSpeed;
t_camAnimPos = mainCam.transform.DOMove(endPos, time);
t_camAnimAngle = mainCam.transform.DORotate(endAngle.eulerAngles, time).OnComplete(() => {
if (call != null)
call();
CameraEnable();
});
}
/// <summary>
/// 移动相机:先拉高,再移动到目标视角
/// </summary>
/// <param name="pos"></param>
/// <param name="angle"></param>
public void CamerMoveAnimAfter(Vector3 endPos, Quaternion endAngle, Action call = null)
{
if (t_camAnimAngle != null)
t_camAnimAngle.Kill();
if (t_camAnimPos != null)
t_camAnimPos.Kill();
mainCam.GetComponent<ModelViewer>()._enabled = false;
float dis = (mainCam.transform.position - camInitPos).magnitude;
float time = dis / camMoveSpeed;
Vector3 hightpoint = new Vector3(mainCam.transform.position.x, ModelManager.instance.wudingHeight+10f, mainCam.transform.position.z);
t_camAnimPos = mainCam.transform.DOMove(hightpoint, time);
t_camAnimAngle = mainCam.transform.DORotate(camInitAngle, time).OnComplete(() => {
t_camAnimPos.Kill();
t_camAnimAngle.Kill();
t_camAnimPos = mainCam.transform.DOMove(endPos, time);
t_camAnimAngle = mainCam.transform.DORotate(endAngle.eulerAngles, time).OnComplete(() =>
{
if (call != null)
call();
CameraEnable();
});
});
}
/// <summary>
/// 开启相机可操作性
/// </summary>
private void CameraEnable()
{
mainCam.GetComponent<ModelViewer>().InitTarget();
mainCam.GetComponent<ModelViewer>()._enabled = true;
}
/// <summary>
/// 移动相机:相机在房间内,先回到初始角度再移至目标位置,相机在房间外,直接移动到目标位置
/// </summary>
/// <param name="pos"></param>
/// <param name="angle"></param>
public void CameraMoveAnim(Vector3 endPos, Quaternion endAngle, Action call = null)
{
bool inview = true;
//判断物体是否在相机视角内TODO:前方是否有物体遮挡
Vector3 viewPos = mainCam.WorldToViewportPoint(endPos);
// z<0代表在相机背后
if (viewPos.z < 0)
inview = false;
//太远了!看不到了!
if (viewPos.z > mainCam.farClipPlane)
inview = false;
// x,y取值在 0~1之外时代表在视角范围外
if (viewPos.x < 0 || viewPos.y < 0 || viewPos.x > 1 || viewPos.y > 1)
inview = false;
if (inview)
{
CameraMoveTarget(endPos, endAngle, call);
}
else
{
CamerMoveAnimAfter(endPos, endAngle, call);
}
}
/// <summary>
/// 视角居中
/// </summary>
/// <param name="curPoint">当前居中的点位</param>
/// <param name="forward">当前居中的点位</param>
/// <param name="dis">当前居中的点位</param>
public void ViewCenterPoint(GameObject curPoint, Vector3 forward, float dis = 3, Action call = null)
{
Debug.Log("web:" + curPoint.name);
//获取模型中心点位置(加上模型方向*3
Vector3 playerPos = curPoint.transform.position + forward * dis;
Quaternion angle = Quaternion.LookRotation(-forward); ;
Debug.Log("pos" + playerPos + ";angle" + angle);
CameraMoveAnim(playerPos, angle, call);
}
}