using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraMove : MonoBehaviour { public static CameraMove instance; [Header("模型以及相机初始位置,自动初始化")] public Vector3 cameraInitialPos; public Vector3 cameraInitialRot; public Vector3 modelInitialRot; [Header("要控制的物体")] [Tooltip("要控制的相机")] public Camera myCamera; [Tooltip("相机缩放的焦点")] public Transform zoomTarget; [Tooltip("要观察的模型")] public Transform model; [Header("设置的参数")] [Tooltip("缩放速率")] public int zoomRate = 40; [Tooltip("最远观察距离")] public float maxObservationDis; [Tooltip("最近观察距离")] public float minObservationDis; [Tooltip("水平方向最大移动距离")] public float maxDisH = 2f; [Tooltip("竖直方向最大移动距离")] public float maxDisV = 5f; [Tooltip("水平竖直平面移动速度")] public float deltaMoveSpeed = 2f; [Tooltip("转动时的速度")] public float rotSpeed = 2f; [Tooltip("竖直方向最大旋转角度")] public float maxRotV = 90f; [Header("自动获取的变量,不需赋值")] public float currentObservationDis; public float mouseX; public float mouseY; public Vector3 zoomDir; Vector3 mouseScreenPos; Vector3 mouseWorldPos; float rotV = 0f; /// /// 手指控制的时候各个变量 /// Touch firstFinger; Touch secondFinger; TouchType touchType; Vector2 deltaPos; bool isStartIJudgeLongPress; bool isStartIZoomByTwoFinger; float twoFingerOldDis; float twoFingerNewDis; void Awake() { //Init(); } // Update is called once per frame void Update() { if (UI_manage.inst.FBX_obj.transform.childCount!=0) { model = UI_manage.inst.FBX_obj.transform.GetChild(0); modelInitialRot = model.localEulerAngles; MoveByFinger(); } //PC端调用Move()方法,功能:鼠标左键控制相机平面移动,按住鼠标右键拖动鼠标相机围绕物体旋转,滚轮相机朝着鼠标位子缩放 //Move(); //安卓端调用此方法功能:一个手指活动屏幕模型旋转,一个手指长按屏幕后再滑动模型平面移动,两个手指实现模型朝着两手指中间放大缩小 //MoveByFinger(); } /// /// 初始化 /// public void Init() { instance = this; cameraInitialPos = myCamera.transform.position; cameraInitialRot = myCamera.transform.localEulerAngles; //modelInitialRot = model.localEulerAngles; } #region PC /// /// PC端鼠标控制移动方法 /// private void Move() { MoveByMouse0(); ZoomByScrollWheel(); RotByMouse1(); } /// /// 鼠标右键按住转动摄像机 /// public void RotByMouse1() { if (Input.GetMouseButton(1)) { mouseX = Input.GetAxis("Mouse X"); mouseY = Input.GetAxis("Mouse Y"); if (Mathf.Abs(mouseX) > Mathf.Abs(mouseY)) { if (mouseX < 0) { model.Rotate(Vector3.up, rotSpeed); //myCamera.transform.RotateAround(model.transform.position, Vector3.up, -rotSpeed); } else if (mouseX > 0) { model.Rotate(Vector3.up, -rotSpeed); //myCamera.transform.RotateAround(model.transform.position, Vector3.up, rotSpeed); } } else if (Mathf.Abs(mouseX) < Mathf.Abs(mouseY)) { if (mouseY < 0) { if (rotV < maxRotV) { myCamera.transform.RotateAround(model.transform.position, Vector3.right, rotSpeed); rotV += rotSpeed; } } else if (mouseY > 0) { if (rotV > -maxRotV) { myCamera.transform.RotateAround(model.transform.position, Vector3.right, -rotSpeed); rotV -= rotSpeed; } //if (myCamera.transform.localEulerAngles.x >=90) //{ // myCamera.transform.RotateAround(model.transform.position, Vector3.right, -rotSpeed); //} } } } } /// /// 滑轮键缩放 /// public void ZoomByScrollWheel() { float scrollWheel = Input.GetAxis("Mouse ScrollWheel"); if (scrollWheel != 0) { Vector3 zoomTargetScreenPos = myCamera.WorldToScreenPoint(zoomTarget.position); mouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, zoomTargetScreenPos.z); zoomTarget.position = myCamera.ScreenToWorldPoint(mouseScreenPos); Ray ray = myCamera.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo)) { zoomTarget.position = hitInfo.point; } } currentObservationDis = (zoomTarget.position - myCamera.transform.position).magnitude; zoomDir = (zoomTarget.position - myCamera.transform.position).normalized; Zoom(zoomDir, scrollWheel * Time.deltaTime * zoomRate); } /// /// 按住鼠标左键拖动 /// public void MoveByMouse0() { if (Input.GetMouseButton(0)) { if (Input.GetAxis("Mouse X") < 0) { //SetMoveSpeed(2.0f); MoveByDeltaDistance(true, true); } else if (Input.GetAxis("Mouse X") > 0) { //SetMoveSpeed(2.0f); MoveByDeltaDistance(true, false); } if (Input.GetAxis("Mouse Y") < 0) { //SetMoveSpeed(2.0f); MoveByDeltaDistance(false, true); } else if (Input.GetAxis("Mouse Y") > 0) { //SetMoveSpeed(2.0f); MoveByDeltaDistance(false, false); } } } /// /// 通过键盘或者方向键或者点击按钮来移动相机 /// /// /// public void MoveByDeltaDistance(bool Hmoving, bool positiveDir) { //target.rotation = transform.rotation; if (Hmoving) { if (positiveDir) { if (myCamera.transform.position.x < maxDisH) { myCamera.transform.Translate(Vector3.right * deltaMoveSpeed * Time.deltaTime, Space.Self); //target.Translate(Vector3.right * deltaMoveSpeed * Time.deltaTime); } } else { if (myCamera.transform.position.x > -maxDisH) { myCamera.transform.Translate(Vector3.right * -deltaMoveSpeed * Time.deltaTime, Space.Self); //target.Translate(Vector3.right * -deltaMoveSpeed * Time.deltaTime); } } } else { if (positiveDir) { if (myCamera.transform.position.y < maxDisH) { myCamera.transform.Translate(transform.up * deltaMoveSpeed * Time.deltaTime, Space.World); //target.Translate(transform.up * deltaMoveSpeed * Time.deltaTime, Space.World); } } else { if (myCamera.transform.position.y > -maxDisH) { myCamera.transform.Translate(transform.up * -deltaMoveSpeed * Time.deltaTime, Space.World); //target.Translate(transform.up * -deltaMoveSpeed * Time.deltaTime, Space.World); } } } } #endregion /// /// 安卓端通过手指控制 /// private void MoveByFinger() { if (Input.touchCount == 0) { touchType = TouchType.NoneFinger; StopAllCoroutines(); isStartIJudgeLongPress = false; isStartIZoomByTwoFinger = false; } else if (Input.touchCount == 1) { if (touchType == TouchType.NoneFinger && !isStartIJudgeLongPress) { isStartIJudgeLongPress = true; StartCoroutine(IJudgeLongPress()); firstFinger = Input.GetTouch(0); } } else if (Input.touchCount == 2) { touchType = TouchType.TwoFingerZoom; } switch (touchType) { case TouchType.NoneFinger: break; case TouchType.OneFingerMove: //MoveByOneFinger(); break; case TouchType.OneFingerRot: RotByOneFinger(); break; case TouchType.TwoFingerZoom: if (!isStartIZoomByTwoFinger) { isStartIZoomByTwoFinger = true; StartCoroutine("IZoomByTwoFinger"); } break; default: break; } } /// /// 判断是否长按 /// /// IEnumerator IJudgeLongPress() { if (Input.touchCount != 0) { Vector2 firstPos = Input.GetTouch(0).position; yield return new WaitForSeconds(0.2f); if (Input.touchCount != 0) { Vector2 secondPos = Input.GetTouch(0).position; if ((secondPos - firstPos).magnitude < 2f) { touchType = TouchType.OneFingerMove; } else { touchType = TouchType.OneFingerRot; } } } } /// /// 相机向物体移动 /// /// 移动方向 /// 移动距离 public void Zoom(Vector3 zoomDir, float zoomDis) { //target.Translate(zoomDir * zoomDis, Space.World); if (zoomDis < 0 && currentObservationDis > maxObservationDis) { return; } else if (zoomDis > 0 && currentObservationDis < minObservationDis) { return; } myCamera.transform.Translate(zoomDir * zoomDis, Space.World); } /// /// 一根手指拖动 /// public void MoveByOneFinger() { firstFinger = Input.GetTouch(0); if (firstFinger.phase == TouchPhase.Moved) { deltaPos = firstFinger.deltaPosition; if (deltaPos.x < 0) { //SetMoveSpeed(2.0f); MoveByDeltaDistance(true, true); } else if (deltaPos.x > 0) { //SetMoveSpeed(2.0f); MoveByDeltaDistance(true, false); } if (deltaPos.y < 0) { //SetMoveSpeed(2.0f); MoveByDeltaDistance(false, true); } else if (deltaPos.y > 0) { //SetMoveSpeed(2.0f); MoveByDeltaDistance(false, false); } } } /// /// 一根手指长按转动 /// public void RotByOneFinger() { firstFinger = Input.GetTouch(0); if (firstFinger.phase == TouchPhase.Moved) { deltaPos = firstFinger.deltaPosition; mouseX = deltaPos.x; mouseY = deltaPos.y; if (Mathf.Abs(mouseX) > Mathf.Abs(mouseY)) { if (mouseX < 0) { model.Rotate(Vector3.up, rotSpeed); } else if (mouseX > 0) { model.Rotate(Vector3.up, -rotSpeed); } } else if (Mathf.Abs(mouseX) < Mathf.Abs(mouseY)) { if (mouseY < 0) { if (rotV < maxRotV) { myCamera.transform.RotateAround(model.transform.position, Vector3.right, rotSpeed); rotV += rotSpeed; } } else if (mouseY > 0) { if (rotV > -maxRotV) { myCamera.transform.RotateAround(model.transform.position, Vector3.right, -rotSpeed); rotV -= rotSpeed; } //if (myCamera.transform.localEulerAngles.x >=90) //{ // myCamera.transform.RotateAround(model.transform.position, Vector3.right, -rotSpeed); //} } } } } /// /// 两根手指缩放协程 /// public IEnumerator IZoomByTwoFinger() { Vector2 centerPos; while (true) { firstFinger = Input.GetTouch(0); secondFinger = Input.GetTouch(1); twoFingerOldDis = Vector2.Distance(firstFinger.position, secondFinger.position); centerPos = (firstFinger.position + secondFinger.position) / 2; yield return 0; firstFinger = Input.GetTouch(0); secondFinger = Input.GetTouch(1); twoFingerNewDis = Vector2.Distance(firstFinger.position, secondFinger.position); float scrollWheel = twoFingerNewDis - twoFingerOldDis; if (scrollWheel != 0) { Vector3 zoomTargetScreenPos = myCamera.WorldToScreenPoint(zoomTarget.position); mouseScreenPos = new Vector3(centerPos.x, centerPos.y, zoomTargetScreenPos.z); zoomTarget.position = myCamera.ScreenToWorldPoint(mouseScreenPos); Ray ray = myCamera.ScreenPointToRay(centerPos); RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo)) { zoomTarget.position = hitInfo.point; } } currentObservationDis = (zoomTarget.position - myCamera.transform.position).magnitude; zoomDir = (zoomTarget.position - myCamera.transform.position).normalized; Zoom(zoomDir, scrollWheel * Time.deltaTime * zoomRate * 0.1f); if (Input.touchCount != 2) { isStartIZoomByTwoFinger = false; break; } } } /// /// 复位方法 /// public void Reset() { myCamera.transform.position = cameraInitialPos; myCamera.transform.localEulerAngles = cameraInitialRot; model.localEulerAngles = modelInitialRot; rotV = 0; } } public enum TouchType { NoneFinger, OneFingerMove, OneFingerRot, TwoFingerZoom }