WindowsFollow.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using UnityEngine;
  2. using Rokid.UXR;
  3. namespace Rokid.UXR.Utility {
  4. [ExecuteAlways]
  5. public class WindowsFollow : MonoBehaviour
  6. {
  7. [Header("Window Settings")]
  8. [SerializeField, Tooltip("What part of the view port to anchor the window to.")]
  9. private TextAnchor windowAnchor = TextAnchor.LowerCenter;
  10. public TextAnchor WindowAnchor
  11. {
  12. get { return windowAnchor; }
  13. set { windowAnchor = value; }
  14. }
  15. [SerializeField, Tooltip("The offset from the view port center applied based on the window anchor selection.")]
  16. private Vector2 windowOffset = new Vector2(0.1f, 0.1f);
  17. public Vector2 WindowOffset
  18. {
  19. get { return windowOffset; }
  20. set { windowOffset = value; }
  21. }
  22. [SerializeField, Range(0.5f, 5.0f), Tooltip("Use to scale the window size up or down, can simulate a zooming effect.")]
  23. private float windowScale = 1.0f;
  24. public float WindowScale
  25. {
  26. get { return windowScale; }
  27. set { windowScale = Mathf.Clamp(value, 0.5f, 5.0f); }
  28. }
  29. [SerializeField, Range(0.0f, 100.0f), Tooltip("How quickly to interpolate the window towards its target position and rotation.")]
  30. private float windowFollowSpeed = 5.0f;
  31. [SerializeField]
  32. private float windowDistance = 10;
  33. public float WindowFollowSpeed
  34. {
  35. get { return windowFollowSpeed; }
  36. set { windowFollowSpeed = Mathf.Abs(value); }
  37. }
  38. private Quaternion windowHorizontalRotation;
  39. private Quaternion windowHorizontalRotationInverse;
  40. private Quaternion windowVerticalRotation;
  41. private Quaternion windowVerticalRotationInverse;
  42. private static readonly Vector2 defaultWindowRotation = Vector2.zero;
  43. private static readonly Vector3 defaultWindowScale = Vector3.one;
  44. private Transform window;
  45. private void Start()
  46. {
  47. windowHorizontalRotation = Quaternion.AngleAxis(defaultWindowRotation.y, Vector3.right);
  48. windowHorizontalRotationInverse = Quaternion.Inverse(windowHorizontalRotation);
  49. windowVerticalRotation = Quaternion.AngleAxis(defaultWindowRotation.x, Vector3.up);
  50. windowVerticalRotationInverse = Quaternion.Inverse(windowVerticalRotation);
  51. window = transform;
  52. }
  53. private void LateUpdate()
  54. {
  55. Transform cameraTransform = MainCameraCache.mainCamera.transform;
  56. float t = Time.deltaTime * windowFollowSpeed;
  57. window.position = Vector3.Lerp(window.position, CalculateWindowPosition(cameraTransform), t);
  58. window.rotation = Quaternion.Slerp(window.rotation, CalculateWindowRotation(cameraTransform), t);
  59. window.localScale = defaultWindowScale * windowScale;
  60. }
  61. private Vector3 CalculateWindowPosition(Transform cameraTransform)
  62. {
  63. Vector3 position = cameraTransform.position + (cameraTransform.forward * windowDistance);
  64. Vector3 horizontalOffset = cameraTransform.right * windowOffset.x;
  65. Vector3 verticalOffset = cameraTransform.up * windowOffset.y;
  66. switch (windowAnchor)
  67. {
  68. case TextAnchor.UpperLeft: position += verticalOffset - horizontalOffset; break;
  69. case TextAnchor.UpperCenter: position += verticalOffset; break;
  70. case TextAnchor.UpperRight: position += verticalOffset + horizontalOffset; break;
  71. case TextAnchor.MiddleLeft: position -= horizontalOffset; break;
  72. case TextAnchor.MiddleRight: position += horizontalOffset; break;
  73. case TextAnchor.LowerLeft: position -= verticalOffset + horizontalOffset; break;
  74. case TextAnchor.LowerCenter: position -= verticalOffset; break;
  75. case TextAnchor.LowerRight: position -= verticalOffset - horizontalOffset; break;
  76. }
  77. return position;
  78. }
  79. private Quaternion CalculateWindowRotation(Transform cameraTransform)
  80. {
  81. Quaternion rotation = MainCameraCache.mainCamera.transform.rotation;
  82. switch (windowAnchor)
  83. {
  84. case TextAnchor.UpperLeft: rotation *= windowHorizontalRotationInverse * windowVerticalRotationInverse; break;
  85. case TextAnchor.UpperCenter: rotation *= windowHorizontalRotationInverse; break;
  86. case TextAnchor.UpperRight: rotation *= windowHorizontalRotationInverse * windowVerticalRotation; break;
  87. case TextAnchor.MiddleLeft: rotation *= windowVerticalRotationInverse; break;
  88. case TextAnchor.MiddleRight: rotation *= windowVerticalRotation; break;
  89. case TextAnchor.LowerLeft: rotation *= windowHorizontalRotation * windowVerticalRotationInverse; break;
  90. case TextAnchor.LowerCenter: rotation *= windowHorizontalRotation; break;
  91. case TextAnchor.LowerRight: rotation *= windowHorizontalRotation * windowVerticalRotation; break;
  92. }
  93. return rotation;
  94. }
  95. }
  96. }