CameraSmoothFollow.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. using UnityEngine;
  10. namespace NRKernal.NRExamples
  11. {
  12. /// <summary> A camera smooth follow. </summary>
  13. public class CameraSmoothFollow : MonoBehaviour
  14. {
  15. /// <summary> The anchor. </summary>
  16. [Header("Window Settings")]
  17. [SerializeField, Tooltip("What part of the view port to anchor the window to.")]
  18. private TextAnchor Anchor = TextAnchor.LowerCenter;
  19. /// <summary> The follow speed. </summary>
  20. [SerializeField, Range(0.0f, 100.0f), Tooltip("How quickly to interpolate the window towards its target position and rotation.")]
  21. private float FollowSpeed = 5.0f;
  22. /// <summary> The default distance. </summary>
  23. private float defaultDistance;
  24. /// <summary> default rotation at start. </summary>
  25. private Vector2 defaultRotation = new Vector2(0f, 0f);
  26. /// <summary> The horizontal rotation. </summary>
  27. private Quaternion HorizontalRotation;
  28. /// <summary> The horizontal rotation inverse. </summary>
  29. private Quaternion HorizontalRotationInverse;
  30. /// <summary> The vertical rotation. </summary>
  31. private Quaternion VerticalRotation;
  32. /// <summary> The vertical rotation inverse. </summary>
  33. private Quaternion VerticalRotationInverse;
  34. /// <summary> The offset. </summary>
  35. [SerializeField, Tooltip("The offset from the view port center applied based on the window anchor selection.")]
  36. private Vector2 Offset = new Vector2(0.1f, 0.1f);
  37. private Transform m_CenterCamera;
  38. private Transform CenterCamera
  39. {
  40. get
  41. {
  42. if (m_CenterCamera == null)
  43. {
  44. if (NRSessionManager.Instance.CenterCameraAnchor != null)
  45. {
  46. m_CenterCamera = NRSessionManager.Instance.CenterCameraAnchor;
  47. }
  48. else if (Camera.main != null)
  49. {
  50. m_CenterCamera = Camera.main.transform;
  51. }
  52. }
  53. return m_CenterCamera;
  54. }
  55. }
  56. /// <summary> Starts this object. </summary>
  57. void Start()
  58. {
  59. HorizontalRotation = Quaternion.AngleAxis(defaultRotation.y, Vector3.right);
  60. HorizontalRotationInverse = Quaternion.Inverse(HorizontalRotation);
  61. VerticalRotation = Quaternion.AngleAxis(defaultRotation.x, Vector3.up);
  62. VerticalRotationInverse = Quaternion.Inverse(VerticalRotation);
  63. defaultDistance = Vector3.Distance(transform.position, CenterCamera.position);
  64. }
  65. /// <summary> Late update. </summary>
  66. private void LateUpdate()
  67. {
  68. if (CenterCamera == null)
  69. {
  70. return;
  71. }
  72. float t = Time.deltaTime * FollowSpeed;
  73. transform.position = Vector3.Lerp(transform.position, CalculatePosition(CenterCamera), t);
  74. transform.rotation = Quaternion.Slerp(transform.rotation, CalculateRotation(CenterCamera), t);
  75. }
  76. /// <summary> Calculates the position. </summary>
  77. /// <param name="cameraTransform"> The camera transform.</param>
  78. /// <returns> The calculated position. </returns>
  79. private Vector3 CalculatePosition(Transform cameraTransform)
  80. {
  81. Vector3 position = cameraTransform.position + (cameraTransform.forward * defaultDistance);
  82. Vector3 horizontalOffset = cameraTransform.right * Offset.x;
  83. Vector3 verticalOffset = cameraTransform.up * Offset.y;
  84. switch (Anchor)
  85. {
  86. case TextAnchor.UpperLeft: position += verticalOffset - horizontalOffset; break;
  87. case TextAnchor.UpperCenter: position += verticalOffset; break;
  88. case TextAnchor.UpperRight: position += verticalOffset + horizontalOffset; break;
  89. case TextAnchor.MiddleLeft: position -= horizontalOffset; break;
  90. case TextAnchor.MiddleRight: position += horizontalOffset; break;
  91. case TextAnchor.LowerLeft: position -= verticalOffset + horizontalOffset; break;
  92. case TextAnchor.LowerCenter: position -= verticalOffset; break;
  93. case TextAnchor.LowerRight: position -= verticalOffset - horizontalOffset; break;
  94. }
  95. return position;
  96. }
  97. /// <summary> Calculates the rotation. </summary>
  98. /// <param name="cameraTransform"> The camera transform.</param>
  99. /// <returns> The calculated rotation. </returns>
  100. private Quaternion CalculateRotation(Transform cameraTransform)
  101. {
  102. Quaternion rotation = cameraTransform.rotation;
  103. switch (Anchor)
  104. {
  105. case TextAnchor.UpperLeft: rotation *= HorizontalRotationInverse * VerticalRotationInverse; break;
  106. case TextAnchor.UpperCenter: rotation *= HorizontalRotationInverse; break;
  107. case TextAnchor.UpperRight: rotation *= HorizontalRotationInverse * VerticalRotation; break;
  108. case TextAnchor.MiddleLeft: rotation *= VerticalRotationInverse; break;
  109. case TextAnchor.MiddleRight: rotation *= VerticalRotation; break;
  110. case TextAnchor.LowerLeft: rotation *= HorizontalRotation * VerticalRotationInverse; break;
  111. case TextAnchor.LowerCenter: rotation *= HorizontalRotation; break;
  112. case TextAnchor.LowerRight: rotation *= HorizontalRotation * VerticalRotation; break;
  113. }
  114. return rotation;
  115. }
  116. }
  117. }