Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
2.9 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using UnityEngine;
  5. using VRTK;
  6. public class CoriolisDisplay : MonoBehaviour
  7. {
  8. [Header("References")]
  9. [SerializeField]
  10. private RotationController m_ship;
  11. [SerializeField]
  12. private GameObject m_segmentPrefab;
  13. [SerializeField]
  14. private Transform m_tip;
  15. [Header("settings")]
  16. [SerializeField]
  17. private int m_segmentCount = 20;
  18. [SerializeField]
  19. private float m_segmentSpacing = 0.5f;
  20. [SerializeField]
  21. private float m_coriolisMultiplier = 1;
  22. private VRTK_InteractableObject m_interactable;
  23. private List<GameObject> m_segments = new List<GameObject>();
  24. private void Awake()
  25. {
  26. if (m_ship == null)
  27. m_ship = FindObjectOfType<RotationController>();
  28. m_interactable = GetComponent<VRTK_InteractableObject>();
  29. }
  30. private void OnEnable()
  31. {
  32. RegisterEvents(true);
  33. }
  34. private void OnDisable()
  35. {
  36. RegisterEvents(false);
  37. DestroySegments();
  38. }
  39. private void Update()
  40. {
  41. UpdateSegments();
  42. }
  43. private void GenerateSegments()
  44. {
  45. for (int i = 0; i < m_segmentCount; i++)
  46. {
  47. GameObject segment = Instantiate(m_segmentPrefab);
  48. segment.transform.position = transform.position;
  49. m_segments.Add(segment);
  50. }
  51. }
  52. private void DestroySegments()
  53. {
  54. foreach (GameObject segment in m_segments)
  55. {
  56. Destroy(segment);
  57. }
  58. m_segments.Clear();
  59. }
  60. private void UpdateSegments()
  61. {
  62. if (m_segments == null || m_segments.Count == 0)
  63. return;
  64. Vector3 position = m_tip.position;
  65. Vector3 direction = m_tip.forward;
  66. Vector3 shipDirection = m_ship.RotationAxis;
  67. foreach(GameObject segment in m_segments)
  68. {
  69. Vector3 force = 2 * Vector3.Cross(direction, m_ship.RotationAxis) * (2 * Mathf.PI / m_ship.RotationPeriod);
  70. direction = (direction + force * m_coriolisMultiplier).normalized * m_segmentSpacing;
  71. position = position + direction;
  72. segment.transform.position = position;
  73. segment.transform.forward = direction;
  74. }
  75. }
  76. private void OnGrab(object sender, InteractableObjectEventArgs args)
  77. {
  78. GenerateSegments();
  79. }
  80. private void OnDrop(object sender, InteractableObjectEventArgs args)
  81. {
  82. DestroySegments();
  83. }
  84. private void RegisterEvents(bool value)
  85. {
  86. if (value)
  87. {
  88. m_interactable.InteractableObjectGrabbed += OnGrab;
  89. m_interactable.InteractableObjectUngrabbed += OnDrop;
  90. }
  91. else
  92. {
  93. m_interactable.InteractableObjectGrabbed -= OnGrab;
  94. m_interactable.InteractableObjectUngrabbed -= OnDrop;
  95. }
  96. }
  97. }