CameraFollower.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace SC.XR.Unity
  5. {
  6. public class CameraFollower : FollowerBase
  7. {
  8. [Header("Following Settings")]
  9. public bool InstantFollowing;//是否无延迟跟随
  10. public bool LinearFollowing;//是否线性移动
  11. public Vector2 menu_size;//面板的长宽,默认面板的position在中心。
  12. private Transform _slamHead;
  13. Vector2 initViewPoint;//相机画面的中点,坐标为(0.5f,0.5f)
  14. Vector3 viewPoint = Vector3.zero;// 面板坐标相对于相机画面的坐标。
  15. Vector3 viewPoint_right = Vector3.zero;// 面板的上下左右端相对于相机画面的坐标。
  16. Vector3 viewPoint_left = Vector3.zero;
  17. Vector3 viewPoint_top = Vector3.zero;
  18. Vector3 viewPoint_bot = Vector3.zero;
  19. bool isFollower = false;
  20. Vector3 originPos = Vector3.zero;
  21. Vector3 desPos = Vector3.zero;
  22. float journeyLength = 0f;
  23. void Start()
  24. {
  25. _slamHead = Camera.main.transform;
  26. initViewPoint = Camera.main.WorldToViewportPoint(_slamHead.position + (_slamHead.forward * WindowDistance));
  27. InstantFollow();
  28. }
  29. //Nonlinear Following by default
  30. protected override void Follow()
  31. {
  32. if (Camera.main == null)
  33. {
  34. return;
  35. }
  36. transform.position = Vector3.Lerp(transform.position, CalculateWindowPosition(Camera.main.transform), WindowFollowSpeed * Time.deltaTime);
  37. transform.rotation = Quaternion.Slerp(transform.rotation, CalculateWindowRotation(Camera.main.transform), WindowFollowSpeed * Time.deltaTime);
  38. }
  39. //Following camera without latency
  40. protected void InstantFollow()
  41. {
  42. transform.position = CalculateWindowPosition(Camera.main.transform);
  43. transform.rotation = CalculateWindowRotation(Camera.main.transform);
  44. }
  45. //For Linear Following, turn down the WindowFollowSpeed to around 0.5 at distance = 1 for best experience
  46. protected void LinearFollow()
  47. {
  48. originPos = transform.position;
  49. desPos = CalculateWindowPosition(Camera.main.transform);
  50. journeyLength = Vector3.Distance(originPos, desPos);
  51. transform.position = Vector3.Lerp(originPos, desPos, (Time.fixedDeltaTime) / journeyLength * WindowFollowSpeed);
  52. transform.rotation = Quaternion.Slerp(transform.rotation, CalculateWindowRotation(Camera.main.transform), (Time.fixedDeltaTime) / journeyLength * WindowFollowSpeed);
  53. }
  54. protected override void LateUpdate()
  55. {
  56. if ((StopFollower == false)&& !InstantFollowing)
  57. {
  58. if (IsFollower() && !LinearFollowing)
  59. {
  60. Follow();
  61. }
  62. else if (IsFollower() && LinearFollowing)
  63. {
  64. LinearFollow();
  65. }
  66. }
  67. else if ((StopFollower == false) && InstantFollowing)
  68. {
  69. InstantFollow();
  70. }
  71. }
  72. protected bool IsFollower()
  73. {
  74. if (Camera.main == null || Camera.main == null)
  75. {
  76. return false;
  77. }
  78. viewPoint = Camera.main.WorldToViewportPoint(transform.position);// 面板在相机画面上的坐标
  79. viewPoint_right = Camera.main.WorldToViewportPoint(transform.TransformPoint(new Vector3(menu_size.x/2, 0, 0)));// 面板边界在相机画面上的坐标
  80. viewPoint_left = Camera.main.WorldToViewportPoint(transform.TransformPoint(new Vector3(-menu_size.x/2, 0, 0)));
  81. viewPoint_top = Camera.main.WorldToViewportPoint(transform.TransformPoint(new Vector3(0, menu_size.y/2, 0)));
  82. viewPoint_bot = Camera.main.WorldToViewportPoint(transform.TransformPoint(new Vector3(0, -menu_size.y/2, 0)));
  83. if (viewPoint_right.x > 1 || viewPoint_left.x < 0 || viewPoint_bot.y < 0 || viewPoint_top.y > 1)//边界判断
  84. {
  85. isFollower = true;
  86. }
  87. else if (Mathf.Abs(viewPoint.x - initViewPoint.x) < 0.05f && Mathf.Abs(viewPoint.y - initViewPoint.y) < 0.05f)//停止跟随的边界判断
  88. {
  89. isFollower = false;
  90. }
  91. return isFollower;
  92. }
  93. }
  94. }