MainCameraLogic.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. public class MainCameraLogic : MonoBehaviour
  6. {
  7. // Start is called before the first frame update
  8. private GameObject mainCamera;
  9. //private GameObject emptyCamera;
  10. public Button btnResetView;
  11. private bool wPressed;
  12. private bool sPressed;
  13. private bool aPressed;
  14. private bool dPressed;
  15. //相机跟随的目标物体,一般是一个空物体
  16. public Transform target;
  17. private int MouseWheelSensitivity = 3; //滚轮灵敏度设置
  18. private int MouseZoomMin = -50; //相机距离最小值
  19. private int MouseZoomMax = 50; //相机距离最大值
  20. //0.06这个系数是控制平移的速度,要根据相机和目标物体的distance来灵活选择
  21. const float centerMoveSpeed = 0.01f;
  22. private const int keyMoveSpeed = 1;
  23. private float moveSpeed = 5; //相机跟随速度(中键平移时),采用平滑模式时起作用,越大则运动越平滑
  24. private float xSpeed = 80.0f; //旋转视角时相机x轴转速
  25. private float ySpeed = 80.0f; //旋转视角时相机y轴转速
  26. private int yMinLimit = -360;
  27. private int yMaxLimit = 360;
  28. private float x = 0.0f; //存储相机的euler角
  29. private float y = 0.0f; //存储相机的euler角
  30. private float Distance = 5; //相机和target之间的距离,因为相机的Z轴总是指向target,也就是相机z轴方向上的距离
  31. private Vector3 targetOnScreenPosition; //目标的屏幕坐标,第三个值为z轴距离
  32. private Quaternion storeRotation; //存储相机的姿态四元数
  33. private Vector3 CameraTargetPosition; //target的位置
  34. private Vector3 initPosition; //平移时用于存储平移的起点位置
  35. private Vector3 cameraX; //相机的x轴方向向量
  36. private Vector3 cameraY; //相机的y轴方向向量
  37. private Vector3 cameraZ; //相机的z轴方向向量
  38. private Vector3 initScreenPos; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用)
  39. private Vector3 curScreenPos; //当前鼠标的屏幕坐标(第三个值其实没什么用)
  40. // Start is called before the first frame update
  41. void Start()
  42. {
  43. mainCamera = GameObject.Find("Main Camera");
  44. //emptyCamera = GameObject.Find("EmptyCamera");
  45. // Debug.Log("Camera x: "+transform.right);
  46. // Debug.Log("Camera y: "+transform.up);
  47. // Debug.Log("Camera z: "+transform.forward);
  48. // //-------------TEST-----------------
  49. // testScreenToWorldPoint();
  50. }
  51. // Update is called once per frame
  52. void Update()
  53. {
  54. //这里就是设置一下初始的相机视角以及一些其他变量,这里的x和y。。。是和下面getAxis的mouse x与mouse y对应
  55. var angles = transform.eulerAngles;
  56. x = angles.y;
  57. y = angles.x;
  58. CameraTargetPosition = target.position;
  59. target.rotation = transform.rotation;
  60. //CameraTargetPosition = transform.position;
  61. //storeRotation = Quaternion.Euler(y + 60, x, 0);
  62. storeRotation = Quaternion.Euler(y, x, 0);
  63. transform.rotation = storeRotation; //设置相机姿态
  64. Vector3 position = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + CameraTargetPosition; //四元数表示一个旋转,四元数乘以向量相当于把向量旋转对应角度,然后加上目标物体的位置就是相机位置了
  65. transform.position = storeRotation * new Vector3(0, 0, -Distance) + CameraTargetPosition; //设置相机位置
  66. //鼠标右键旋转功能
  67. if (Input.GetMouseButton(1))
  68. {
  69. x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
  70. y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
  71. y = ClampAngle(y, yMinLimit, yMaxLimit);
  72. //storeRotation = Quaternion.Euler(y + 60, x, 0);
  73. storeRotation = Quaternion.Euler(y, x, 0);
  74. var tmpPosition = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;
  75. transform.rotation = storeRotation;
  76. transform.position = tmpPosition;
  77. }
  78. else if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
  79. {
  80. if (Distance >= MouseZoomMin && Distance <= MouseZoomMax)
  81. {
  82. Distance -= Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity;
  83. }
  84. if (Distance < MouseZoomMin)
  85. {
  86. Distance = MouseZoomMin;
  87. }
  88. if (Distance > MouseZoomMax)
  89. {
  90. Distance = MouseZoomMax;
  91. }
  92. var rotation = transform.rotation;
  93. transform.position = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + CameraTargetPosition;
  94. }
  95. //鼠标中键平移
  96. if (Input.GetMouseButtonDown(2))
  97. {
  98. cameraX = transform.right;
  99. cameraY = transform.up;
  100. cameraZ = transform.forward;
  101. initScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
  102. Debug.Log("downOnce");
  103. //targetOnScreenPosition.z为目标物体到相机xmidbuttonDownPositiony平面的法线距离
  104. targetOnScreenPosition = Camera.main.WorldToScreenPoint(CameraTargetPosition);
  105. initPosition = CameraTargetPosition;
  106. }
  107. if (Input.GetMouseButton(2))
  108. {
  109. curScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
  110. target.position = initPosition - centerMoveSpeed * ((curScreenPos.x - initScreenPos.x) * cameraX + (curScreenPos.y - initScreenPos.y) * cameraY);
  111. //重新计算位置
  112. Vector3 mPosition = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + target.position;
  113. transform.position = mPosition;
  114. // //用这个会让相机的平移变得更平滑,但是可能在你buttonup时未使相机移动到应到的位置,导致再进行旋转与缩放操作时出现短暂抖动
  115. //transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);
  116. }
  117. if (Input.GetMouseButtonUp(2))
  118. {
  119. Debug.Log("upOnce");
  120. //平移结束把cameraTargetPosition的位置更新一下,不然会影响缩放与旋转功能
  121. CameraTargetPosition = target.position;
  122. }
  123. if (Input.GetKeyDown(KeyCode.D))
  124. {
  125. dPressed = true;
  126. }
  127. if (Input.GetKeyDown(KeyCode.A))
  128. {
  129. aPressed = true;
  130. }
  131. if (Input.GetKeyUp(KeyCode.A))
  132. {
  133. Debug.Log("A up");
  134. aPressed = false;
  135. }
  136. if (Input.GetKeyUp(KeyCode.W))
  137. {
  138. Debug.Log("W up");
  139. wPressed = false;
  140. }
  141. if (Input.GetKeyUp(KeyCode.S))
  142. {
  143. Debug.Log("s up");
  144. sPressed = false;
  145. }
  146. if (Input.GetKeyUp(KeyCode.D))
  147. {
  148. Debug.Log("d up");
  149. dPressed = false;
  150. }
  151. if (Input.GetKeyDown(KeyCode.W))
  152. {
  153. wPressed = true;
  154. Debug.Log("W Pressed");
  155. }
  156. if (Input.GetKeyDown(KeyCode.S))
  157. {
  158. sPressed = true;
  159. }
  160. keyMove();
  161. }
  162. void keyMove()
  163. {
  164. if (wPressed)
  165. {
  166. target.transform.Translate(0, 0, keyMoveSpeed * Time.deltaTime, Space.Self);
  167. }
  168. if (sPressed)
  169. {
  170. target.transform.Translate(0, 0, -keyMoveSpeed * Time.deltaTime, Space.Self);
  171. }
  172. if (dPressed)
  173. {
  174. // x += xSpeed * 0.002f;
  175. //// y -= ySpeed * 0.02f;
  176. // y = ClampAngle(y, yMinLimit, yMaxLimit);
  177. // //storeRotation = Quaternion.Euler(y + 60, x, 0);
  178. // storeRotation = Quaternion.Euler(y, x, 0);
  179. // var tmpPosition = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;
  180. // transform.rotation = storeRotation;
  181. // transform.position = tmpPosition;
  182. target.transform.Translate(keyMoveSpeed * Time.deltaTime, 0, 0, Space.Self);
  183. }
  184. if (aPressed)
  185. {
  186. //x -= xSpeed * 0.002f;
  187. //y -= ySpeed * 0.02f;
  188. //y = ClampAngle(y, yMinLimit, yMaxLimit);
  189. //storeRotation = Quaternion.Euler(y + 60, x, 0);
  190. //storeRotation = Quaternion.Euler(y, x, 0);
  191. //var tmpPosition = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;
  192. //transform.rotation = storeRotation;
  193. //transform.position = tmpPosition;
  194. target.transform.Translate(-keyMoveSpeed * Time.deltaTime,0,0, Space.Self);
  195. }
  196. }
  197. //将angle限制在min~max之间
  198. static float ClampAngle(float angle, float min, float max)
  199. {
  200. if (angle < -360)
  201. angle += 360;
  202. if (angle > 360)
  203. angle -= 360;
  204. return Mathf.Clamp(angle, min, max);
  205. }
  206. void testScreenToWorldPoint()
  207. {
  208. //第三个坐标指的是在相机z轴指向方向上的距离
  209. Vector3 screenPoint = Camera.main.WorldToScreenPoint(CameraTargetPosition);
  210. Debug.Log("ScreenPoint: " + screenPoint);
  211. // var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(1,1,10));
  212. // Debug.Log("worldPosition: "+worldPosition);
  213. }
  214. /**
  215. * 重置主镜头视角
  216. *
  217. */
  218. public void ResetView()
  219. {
  220. Debug.Log("Reset View!!!");
  221. Vector3 position = new Vector3(62f, 78f, -322f);
  222. mainCamera.transform.position = position;
  223. target.transform.position = position;
  224. Quaternion rotation = Quaternion.Euler(32, 183, 0);
  225. mainCamera.transform.rotation = rotation;
  226. // target.transform.rotation = rotation;
  227. Distance = 5;
  228. }
  229. }