using UnityEngine; using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options; using UnityEngine.EventSystems; using UnityEngine.Events; using System; using GOEventSystem; using DevelopEngine; using System.Collections.Generic; using XFramework; using System.IO; public partial class CameraCtrl : MonoSingleton { CameraPos pos = CameraPos.OutRoom; Camera mainCamera;//主摄像机 public Camera Camera { get { return mainCamera; } } private float camerHor;//相机水平转动输入值 private float camerVer;//相机垂直转动输入值 public UnityAction rightButtonEvent;//右键空白地面事件 bool moveWithRect = true;//边缘检测移动相机 public bool MoveWithRect { get { return moveWithRect; } set { this.moveWithRect = value; } } /// /// 类似游戏 通过鼠标移动到屏幕边界控制镜头移动 /// private Rect rectUp; private Rect rectDown; private Rect rectLeft; private Rect rectRight; public float rectSize=30; public float cameraMoveSpeed=5f; [SerializeField] int mouseKey=0; Terrain terrain; protected void Start() { Init(); GetConfigFromText(); mainCamera = this.GetComponentInChildren(); ChangeCameraCtrlType(CamerViewType.Third); //this.enabled = false; //根据屏幕尺寸确定检测范围 rectUp = new Rect(0, Screen.height - rectSize, Screen.width, rectSize); rectDown = new Rect(0, 0, Screen.width, rectSize); rectLeft = new Rect(0, 0, rectSize, Screen.height); rectRight = new Rect(Screen.width - rectSize, 0, rectSize, Screen.height); cameraMoveSpeed = 120; terrain = Terrain.activeTerrain; //Debug.Log(); } EventSystem_Camera eventSystem_Camera; //添加交互检测器 internal void AddGOEventSystem() { eventSystem_Camera = gameObject.AddComponent(); } public void ChangeCameraEvent(bool isUsed) { eventSystem_Camera?.SetUsed(isUsed); } void Update() { //Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); //Debug.DrawRay(ray.origin, ray.direction * 2000); if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject()) return; //相机控制时屏蔽UI部分 UpdateThird(); } /// /// 改变相机控制状态 /// /// public void ChangeCameraCtrlType(CamerViewType ctrlType) { StartThird(); } public void ChangeCamerPosSet(CameraPos cameraPos) { this.pos = cameraPos; } //开始第三人称控制视角 void StartThird() { switch (pos) { case CameraPos.OutRoom: UpdateFarZoonMoveClamp(); break; case CameraPos.InRoom: UpdateNearZoonMoveClamp(); break; default: break; } ResetCameraAngY(0); ResetCameraAngX(45); //this.gameObject.transform.DOMove(startThirdPos, 0.3f); } //增大缩放空间 public void UpdateFarZoonMoveClamp() { m_ZoonMoveClamp = new Vector2(-150, -35); ResetCameraContainerPos(-50); } //减小缩放空间 public void UpdateNearZoonMoveClamp() { m_ZoonMoveClamp = new Vector2(-10, -2); ResetCameraContainerPos(-5); } //第三人称控制循环 void UpdateThird() { //镜头拉近拉远 ZoonMove(Input.GetAxis("Mouse ScrollWheel")); //右键发射射线确定新的锚点 并移动过去 //if (Input.GetMouseButtonDown(1)) //{ // RaycastHit hit;//鼠标射线检测 // Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // if (Physics.Raycast(ray, out hit, 2000, LayerMask.GetMask("Floor"))) // { // this.gameObject.transform.DOMove(hit.point, 0.3f); // } //} //右键 if (Input.GetMouseButtonDown(1)) { rightButtonEvent?.Invoke(); } //左键按下拖动旋转镜头角度 if (Input.GetMouseButton(mouseKey)) { camerHor = -Input.GetAxis("Mouse X"); camerVer = -Input.GetAxis("Mouse Y"); if (Mathf.Abs(camerHor) > 0.2f || Mathf.Abs(camerVer) > 0.2f) { HerRot(camerHor); UpOrDownRot(camerVer); } } //Debug.Log(Input.mousePosition); #region//鼠标边界平移 保持距离地面的高度 if (moveWithRect) { float terrainHeightChangeValue = 0;//相机正下方地形高度变化值 float cueeentHeight = 0;//当前相机正下方地面高度 float movedHeight = 0;//移动后相机下方地面高度 if (terrain) { cueeentHeight = terrain.SampleHeight(mainCamera.transform.position);//当前相机高度减去地面高度 } if (rectUp.Contains(Input.mousePosition)) { this.transform.position += Vector3.ProjectOnPlane(mainCamera.transform.forward, Vector3.up).normalized * cameraMoveSpeed * Time.deltaTime; //获取相机正前方在水平面的投影向量后改变位置 } if (rectDown.Contains(Input.mousePosition)) { this.transform.position -= Vector3.ProjectOnPlane(mainCamera.transform.forward, Vector3.up).normalized * cameraMoveSpeed * Time.deltaTime; } if (rectRight.Contains(Input.mousePosition)) { this.transform.position += Vector3.ProjectOnPlane(mainCamera.transform.right, Vector3.up).normalized * cameraMoveSpeed * Time.deltaTime; } if (rectLeft.Contains(Input.mousePosition)) { this.transform.position -= Vector3.ProjectOnPlane(mainCamera.transform.right, Vector3.up).normalized * cameraMoveSpeed * Time.deltaTime; } if (terrain) { movedHeight = terrain.SampleHeight(mainCamera.transform.position);//当前相机高度减去地面高度 } terrainHeightChangeValue = movedHeight - cueeentHeight; this.transform.position += new Vector3(0, terrainHeightChangeValue, 0); } #endregion } //获取鼠标点击的某层的物体 无法被其他物体遮挡 #region 装备展示 相机 设置 public bool IsLockHerVerAng; //展示单个设备控制相机转动 public void ShowEquipmentCameraCtrl(int hor, int ver) { camerHor = hor; camerVer = ver; } //展示单独设备循环 void UpdateShowEquipment() { float scrollWheel = Input.GetAxis("Mouse ScrollWheel"); ZoonMove(scrollWheel); #region ui 控制 //if (IsLockHerVerAng) //ui 控制 //{ // if (camerHor != 0 || camerVer != 0) // { // this.transform.RotateAround(lookAtTarget.position, new Vector3(camerVer, camerHor, 0), 20 * Time.deltaTime); // } //} //else //{ //} #endregion if (Input.GetMouseButton(mouseKey)) { camerHor = -Input.GetAxis("Mouse X"); camerVer = -Input.GetAxis("Mouse Y"); if (Mathf.Abs(camerHor) > 0.2f || Mathf.Abs(camerVer) > 0.2f) { HerRot(camerHor); UpOrDownRot(camerVer); } } } #endregion private Transform m_CameraUpOrDown; private Transform m_CameraZoomContainer; private Transform m_CameraContainer; public float m_HerRotSpeed = 200; public float m_VerRotSpeed = 200; public float m_ZoonMoveSpeed = 500; public Vector2 m_VerRotAngClamp = new Vector2(-90, 90); public Vector2 m_ZoonMoveClamp = new Vector2(-float.MaxValue, -5); private void Init() { m_CameraUpOrDown = transform.Find("CameraUpAndDown"); m_CameraZoomContainer = m_CameraUpOrDown.Find("CameraZoomContainer"); m_CameraContainer = m_CameraZoomContainer.Find("CameraContainer"); } #region /// /// 水平转动 /// /// public void HerRot(float rotNum) { transform.Rotate(Vector3.up * Time.deltaTime * m_HerRotSpeed * rotNum); } /// /// 上下转动 /// /// public void UpOrDownRot(float rotNum) { m_CameraUpOrDown.Rotate(-Vector3.right * Time.deltaTime * m_VerRotSpeed * rotNum); m_CameraUpOrDown.localRotation = Quaternion.Euler(new Vector3(Mathf.Clamp(GetAng(m_CameraUpOrDown.eulerAngles.x), m_VerRotAngClamp.x, m_VerRotAngClamp.y), 0, 0)); } /// /// 缩放 拉近 拉远 /// /// public void ZoonMove(float zoonNum) { m_CameraContainer.Translate(Vector3.forward * Time.deltaTime * m_ZoonMoveSpeed * zoonNum); m_CameraContainer.localPosition = new Vector3(0, 0, Mathf.Clamp(m_CameraContainer.localPosition.z, m_ZoonMoveClamp.x, m_ZoonMoveClamp.y)); } /// /// 移动到目标位置 并观察目标 /// /// public void LookAtTarget(Transform target) { this.gameObject.transform.DOMove(target.position, 0.3f); } /// /// 更新位置 /// /// public void UpdatePostion(Vector3 pos) { transform.position = pos; } private float GetAng(float ang) { if (ang > 180) { ang -= 360; } return ang; } #endregion public void ResetCameraContainerPos(float distZ) { m_CameraContainer.localPosition = new Vector3(0, 0, distZ); } public void ResetCameraAngX(float angX) { m_CameraUpOrDown.localEulerAngles = new Vector3(angX, 0, 0); } public void ResetCameraAngY(float angY) { transform.localEulerAngles = new Vector3(0, angY, 0); } private void GetConfigFromText() { string [] strs= File.ReadAllLines(StreamingAssetsManager.GetPath("CameraCtrl")); for (int i = 0; i < strs.Length; i++) { string oneLine = strs[i].Trim(); if (oneLine.StartsWith("RotateKey:")) { mouseKey = int.Parse(oneLine.Split(':')[1]); } } } } public enum CameraPos { OutRoom,//室外 InRoom,//室内 } //相机视角模式 public enum CamerViewType { Tween,//动画 First,//第一人称 Third,//电子沙盘 ShowEquipment,//展示单个设备 } //相机移动控制类型 public enum CameraMoveType { //右键点击地面 rightButtonHitFloor, // }