using System.Collections; using System.Collections.Generic; using UnityEngine; using VRTK; /// /// Class which deals with how objects behave when they are dropped /// [RequireComponent(typeof(VRTK_InteractableObject))] public class GravityData : MonoBehaviour { [Header("Data")] public string Name; public float Gravity; [Header("Visual Settings")] [SerializeField] private Transform m_planet; [SerializeField] private float m_rotationSpeed = 1; [SerializeField] private float m_bounceSpeed = 1; [SerializeField] private float m_bounceAmplitude = 0.1f; private Vector3 m_StartPos; public float m_randomOffset; /// /// The vrtk interactable object on this object /// private VRTK_InteractableObject m_interactable; /// /// Rigid body on this object /// private Rigidbody m_rigid; private void Awake() { //Set up some variables on start m_interactable = GetComponent(); m_rigid = GetComponentInChildren(); m_StartPos = transform.position; m_randomOffset = Random.value * 20; } private void OnEnable() { RegisterEvents(true); } private void OnDisable() { RegisterEvents(false); } private void Update() { if (m_planet != null) { m_planet.Rotate(Vector3.up, 360 / m_rotationSpeed * Time.deltaTime, Space.Self); m_planet.localPosition = Vector3.up * Mathf.Sin(Time.time * m_bounceSpeed + m_randomOffset) * m_bounceAmplitude; } } private void OnGrab(object sender, InteractableObjectEventArgs args) { StopAllCoroutines(); m_rigid.isKinematic = false; } private void OnDrop(object sender, InteractableObjectEventArgs args) { StopAllCoroutines(); StartCoroutine(LerpToPosition(m_StartPos, Quaternion.identity, 2.0f)); } private void OnSnap(object sender, InteractableObjectEventArgs args) { StopAllCoroutines(); //m_rigid.isKinematic = true; } private void RegisterEvents(bool value) { if (value) { m_interactable.InteractableObjectSnappedToDropZone += OnSnap; m_interactable.InteractableObjectGrabbed += OnGrab; m_interactable.InteractableObjectUngrabbed += OnDrop; }else { m_interactable.InteractableObjectSnappedToDropZone -= OnSnap; m_interactable.InteractableObjectGrabbed -= OnGrab; m_interactable.InteractableObjectUngrabbed -= OnDrop; } } #region Coroutines /// /// Lerps object to a position over an amount of time /// /// End position /// End rotation /// Time it takes to lerp private IEnumerator LerpToPosition(Vector3 SnapPos, Quaternion SnapRot, float snapTime) { Debug.Log("Lerp to position"); //This is based off of SteamVR Lerping code float dropTimer = -1; m_rigid.isKinematic = false; //once again this is all steamVR while (dropTimer < 1) { float t = Mathf.Pow(35, dropTimer); m_rigid.velocity = Vector3.Lerp(m_rigid.velocity, Vector3.zero, Time.fixedDeltaTime * 4); if (m_rigid.useGravity) m_rigid.AddForce(-Physics.gravity); transform.position = Vector3.Lerp(transform.position, SnapPos, Time.fixedDeltaTime * t * 3); transform.rotation = Quaternion.Slerp(transform.rotation, SnapRot, Time.fixedDeltaTime * t * 5); yield return new WaitForFixedUpdate(); dropTimer += Time.fixedDeltaTime / (snapTime / 2); } //#Audio: object has just arrived at where it was lerping to //set correct transform in case object stuck m_rigid.isKinematic = true; transform.position = SnapPos; transform.rotation = SnapRot; } #endregion Coroutines }