using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using UnityEngine;
|
|
using VRTK;
|
|
|
|
public class CoriolisDisplay : MonoBehaviour
|
|
{
|
|
|
|
[Header("References")]
|
|
[SerializeField]
|
|
private RotationController m_ship;
|
|
|
|
[SerializeField]
|
|
private GameObject m_segmentPrefab;
|
|
|
|
[SerializeField]
|
|
private Transform m_tip;
|
|
|
|
|
|
[Header("settings")]
|
|
[SerializeField]
|
|
private int m_segmentCount = 20;
|
|
[SerializeField]
|
|
private float m_segmentSpacing = 0.5f;
|
|
[SerializeField]
|
|
private float m_coriolisMultiplier = 1;
|
|
|
|
|
|
|
|
private VRTK_InteractableObject m_interactable;
|
|
private List<GameObject> m_segments = new List<GameObject>();
|
|
|
|
|
|
private void Awake()
|
|
{
|
|
if (m_ship == null)
|
|
m_ship = FindObjectOfType<RotationController>();
|
|
|
|
m_interactable = GetComponent<VRTK_InteractableObject>();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
RegisterEvents(true);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
RegisterEvents(false);
|
|
DestroySegments();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
UpdateSegments();
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GenerateSegments()
|
|
{
|
|
for (int i = 0; i < m_segmentCount; i++)
|
|
{
|
|
GameObject segment = Instantiate(m_segmentPrefab);
|
|
segment.transform.position = transform.position;
|
|
m_segments.Add(segment);
|
|
}
|
|
}
|
|
|
|
private void DestroySegments()
|
|
{
|
|
foreach (GameObject segment in m_segments)
|
|
{
|
|
Destroy(segment);
|
|
}
|
|
|
|
m_segments.Clear();
|
|
}
|
|
|
|
private void UpdateSegments()
|
|
{
|
|
|
|
if (m_segments == null || m_segments.Count == 0)
|
|
return;
|
|
|
|
|
|
Vector3 position = m_tip.position;
|
|
Vector3 direction = m_tip.forward;
|
|
Vector3 shipDirection = m_ship.RotationAxis;
|
|
|
|
foreach(GameObject segment in m_segments)
|
|
{
|
|
|
|
Vector3 force = 2 * Vector3.Cross(direction, m_ship.RotationAxis) * (2 * Mathf.PI / m_ship.RotationPeriod);
|
|
direction = (direction + force * m_coriolisMultiplier).normalized * m_segmentSpacing;
|
|
position = position + direction;
|
|
|
|
segment.transform.position = position;
|
|
segment.transform.forward = direction;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnGrab(object sender, InteractableObjectEventArgs args)
|
|
{
|
|
GenerateSegments();
|
|
}
|
|
|
|
|
|
private void OnDrop(object sender, InteractableObjectEventArgs args)
|
|
{
|
|
DestroySegments();
|
|
}
|
|
|
|
|
|
private void RegisterEvents(bool value)
|
|
{
|
|
if (value)
|
|
{
|
|
m_interactable.InteractableObjectGrabbed += OnGrab;
|
|
m_interactable.InteractableObjectUngrabbed += OnDrop;
|
|
}
|
|
else
|
|
{
|
|
m_interactable.InteractableObjectGrabbed -= OnGrab;
|
|
m_interactable.InteractableObjectUngrabbed -= OnDrop;
|
|
}
|
|
}
|
|
|
|
}
|