KeyboardFollower.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using UnityEngine;
  2. namespace SC.XR.Unity.Module_Keyboard
  3. {
  4. public class KeyboardFollower : FollowerBase
  5. {
  6. [Header("Following Settings")]
  7. public bool LinearFollowing;//Whether is linear movement.
  8. public Vector2 border_x; //x-axis boundary
  9. public Vector2 border_y; //y-axis boundary
  10. private Transform _slamHead;
  11. Vector2 initViewPoint;//The midpoint of the camera frame, the coordinates are (0.5f, 0.5f).
  12. Vector3 viewPoint = Vector3.zero;// Panel coordinates are relative to the coordinates of the camera screen.
  13. private Vector3 velocity = Vector3.zero;
  14. bool isFollower = false;
  15. Vector3 originPos = Vector3.zero;
  16. Vector3 desPos = Vector3.zero;
  17. float journeyLength = 0f;
  18. Vector3 offsetPos;
  19. Quaternion offsetRotation;
  20. Vector3 startScale;
  21. protected override void OnEnable()
  22. {
  23. base.OnEnable();
  24. Vector3 v3 = Camera.main.transform.position + Camera.main.transform.forward * 0.5f;
  25. // transform.position = new Vector3(v3.x, Camera.main.transform.position.y, v3.z); // Vector3.Lerp(transform.position, CalculateWindowPosition(Camera.main.transform), WindowFollowSpeed * Time.deltaTime);
  26. //transform.position = Vector3.SmoothDamp(transform.position, CalculateWindowPosition(Camera.main.transform), ref velocity, WindowFollowSpeed);
  27. transform.LookAt(Camera.main.transform);
  28. }
  29. private void Start()
  30. {
  31. // InitTrans();
  32. startScale = transform.localScale;
  33. }
  34. protected override void LateUpdate()
  35. {
  36. if (StopFollower == false)
  37. {
  38. if (IsFollower())
  39. {
  40. if (LinearFollowing)
  41. {
  42. LinearFollow();
  43. }
  44. else
  45. {
  46. Follow();
  47. }
  48. }
  49. }
  50. transform.localScale = startScale* 1.5f;
  51. }
  52. void InitTrans()
  53. {
  54. if (!this.StopFollower && (Camera.main != null))
  55. {
  56. _slamHead = Camera.main.transform;
  57. transform.position = CalculateWindowPosition(Camera.main.transform);
  58. transform.rotation = CalculateWindowRotation(Camera.main.transform);
  59. initViewPoint = Camera.main.WorldToViewportPoint(_slamHead.position + (_slamHead.forward * WindowDistance));//The coordinates of the midpoint of the camera screen.
  60. }
  61. }
  62. protected bool IsFollower()
  63. {
  64. if ( Camera.main == null)
  65. {
  66. return false;
  67. }
  68. viewPoint = Camera.main.WorldToViewportPoint(transform.position);// The coordinates of the panel on the camera screen.
  69. if (viewPoint.x > initViewPoint.x + border_x.x + CalculateWindowOffsetX() || viewPoint.x < initViewPoint.x + border_x.y + CalculateWindowOffsetX() || viewPoint.y < initViewPoint.y + border_y.y + CalculateWindowOffsetY() || viewPoint.y > initViewPoint.y + border_y.x + CalculateWindowOffsetY())// Boundary judgment
  70. {
  71. isFollower = true;
  72. }
  73. else if (Mathf.Abs(viewPoint.x - initViewPoint.x - CalculateWindowOffsetX()) < 0.05f && Mathf.Abs(viewPoint.y - initViewPoint.y - CalculateWindowOffsetY()) < 0.09f)
  74. {
  75. isFollower = false;
  76. }
  77. return isFollower;
  78. }
  79. //Nonlinear Following by default
  80. protected override void Follow()
  81. {
  82. //transform.position = CalculateWindowPosition(Camera.main.transform); // Vector3.Lerp(transform.position, CalculateWindowPosition(Camera.main.transform), WindowFollowSpeed * Time.deltaTime);
  83. //transform.position = Vector3.SmoothDamp(transform.position, CalculateWindowPosition(Camera.main.transform), ref velocity, WindowFollowSpeed);
  84. // transform.rotation = CalculateWindowRotation(Camera.main.transform);// Quaternion.Slerp(transform.rotation, CalculateWindowRotation(Camera.main.transform), WindowFollowSpeed * Time.deltaTime);
  85. }
  86. //For Linear Following, turn down the WindowFollowSpeed to around 0.5 at distance = 1 for best experience
  87. protected void LinearFollow()
  88. {
  89. originPos = transform.position;
  90. desPos = CalculateWindowPosition(Camera.main.transform);
  91. journeyLength = Vector3.Distance(originPos, desPos);
  92. transform.position = Vector3.Lerp(originPos, desPos, (Time.fixedDeltaTime) / journeyLength * WindowFollowSpeed);
  93. transform.rotation = Quaternion.Slerp(transform.rotation, CalculateWindowRotation(Camera.main.transform), (Time.fixedDeltaTime) / journeyLength * WindowFollowSpeed);
  94. }
  95. protected override Vector3 CalculateWindowPosition(Transform cameraTransform)
  96. {
  97. Vector3 position = cameraTransform.position + (Vector3.ProjectOnPlane(cameraTransform.forward, Vector3.up).normalized * WindowDistance);
  98. Vector3 horizontalOffset = cameraTransform.right * windowOffset.x;
  99. Vector3 verticalOffset = cameraTransform.up * windowOffset.y;
  100. switch (windowAnchor)
  101. {
  102. case TextAnchor.UpperLeft: position += verticalOffset - horizontalOffset; break;
  103. case TextAnchor.UpperCenter: position += verticalOffset; break;
  104. case TextAnchor.UpperRight: position += verticalOffset + horizontalOffset; break;
  105. case TextAnchor.MiddleLeft: position -= horizontalOffset; break;
  106. case TextAnchor.MiddleRight: position += horizontalOffset; break;
  107. case TextAnchor.MiddleCenter: position += horizontalOffset + verticalOffset; break;
  108. case TextAnchor.LowerLeft: position -= verticalOffset + horizontalOffset; break;
  109. case TextAnchor.LowerCenter: position -= verticalOffset; break;
  110. case TextAnchor.LowerRight: position -= verticalOffset - horizontalOffset; break;
  111. }
  112. return position;
  113. }
  114. protected override Quaternion CalculateWindowRotation(Transform cameraTransform)
  115. {
  116. Quaternion rotation = Quaternion.Euler(0, cameraTransform.rotation.eulerAngles.y, 0);
  117. switch (windowAnchor)
  118. {
  119. case TextAnchor.UpperLeft: rotation *= windowHorizontalRotationInverse * windowVerticalRotationInverse; break;
  120. case TextAnchor.UpperCenter: rotation *= windowHorizontalRotationInverse; break;
  121. case TextAnchor.UpperRight: rotation *= windowHorizontalRotationInverse * windowVerticalRotation; break;
  122. case TextAnchor.MiddleLeft: rotation *= windowVerticalRotationInverse; break;
  123. case TextAnchor.MiddleRight: rotation *= windowVerticalRotation; break;
  124. case TextAnchor.LowerLeft: rotation *= windowHorizontalRotation * windowVerticalRotationInverse; break;
  125. case TextAnchor.LowerCenter: rotation *= windowHorizontalRotation; break;
  126. case TextAnchor.LowerRight: rotation *= windowHorizontalRotation * windowVerticalRotation; break;
  127. }
  128. return rotation;
  129. }
  130. }
  131. }