CameraFollower.cs 5.3 KB

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