LinearDrive.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //======= Copyright (c) Valve Corporation, All rights reserved. ===============
  2. //
  3. // Purpose: Drives a linear mapping based on position between 2 positions
  4. //
  5. //=============================================================================
  6. using UnityEngine;
  7. using System.Collections;
  8. namespace Valve.VR.InteractionSystem
  9. {
  10. //-------------------------------------------------------------------------
  11. [RequireComponent( typeof( Interactable ) )]
  12. public class LinearDrive : MonoBehaviour
  13. {
  14. public Transform startPosition;
  15. public Transform endPosition;
  16. public LinearMapping linearMapping;
  17. public bool repositionGameObject = true;
  18. public bool maintainMomemntum = true;
  19. public float momemtumDampenRate = 5.0f;
  20. private float initialMappingOffset;
  21. private int numMappingChangeSamples = 5;
  22. private float[] mappingChangeSamples;
  23. private float prevMapping = 0.0f;
  24. private float mappingChangeRate;
  25. private int sampleCount = 0;
  26. //-------------------------------------------------
  27. void Awake()
  28. {
  29. mappingChangeSamples = new float[numMappingChangeSamples];
  30. }
  31. //-------------------------------------------------
  32. void Start()
  33. {
  34. if ( linearMapping == null )
  35. {
  36. linearMapping = GetComponent<LinearMapping>();
  37. }
  38. if ( linearMapping == null )
  39. {
  40. linearMapping = gameObject.AddComponent<LinearMapping>();
  41. }
  42. initialMappingOffset = linearMapping.value;
  43. if ( repositionGameObject )
  44. {
  45. UpdateLinearMapping( transform );
  46. }
  47. }
  48. //-------------------------------------------------
  49. private void HandHoverUpdate( Hand hand )
  50. {
  51. if ( hand.GetStandardInteractionButtonDown() )
  52. {
  53. hand.HoverLock( GetComponent<Interactable>() );
  54. initialMappingOffset = linearMapping.value - CalculateLinearMapping( hand.transform );
  55. sampleCount = 0;
  56. mappingChangeRate = 0.0f;
  57. }
  58. if ( hand.GetStandardInteractionButtonUp() )
  59. {
  60. hand.HoverUnlock( GetComponent<Interactable>() );
  61. CalculateMappingChangeRate();
  62. }
  63. if ( hand.GetStandardInteractionButton() )
  64. {
  65. UpdateLinearMapping( hand.transform );
  66. }
  67. }
  68. //-------------------------------------------------
  69. private void CalculateMappingChangeRate()
  70. {
  71. //Compute the mapping change rate
  72. mappingChangeRate = 0.0f;
  73. int mappingSamplesCount = Mathf.Min( sampleCount, mappingChangeSamples.Length );
  74. if ( mappingSamplesCount != 0 )
  75. {
  76. for ( int i = 0; i < mappingSamplesCount; ++i )
  77. {
  78. mappingChangeRate += mappingChangeSamples[i];
  79. }
  80. mappingChangeRate /= mappingSamplesCount;
  81. }
  82. }
  83. //-------------------------------------------------
  84. private void UpdateLinearMapping( Transform tr )
  85. {
  86. prevMapping = linearMapping.value;
  87. linearMapping.value = Mathf.Clamp01( initialMappingOffset + CalculateLinearMapping( tr ) );
  88. mappingChangeSamples[sampleCount % mappingChangeSamples.Length] = ( 1.0f / Time.deltaTime ) * ( linearMapping.value - prevMapping );
  89. sampleCount++;
  90. if ( repositionGameObject )
  91. {
  92. transform.position = Vector3.Lerp( startPosition.position, endPosition.position, linearMapping.value );
  93. }
  94. }
  95. //-------------------------------------------------
  96. private float CalculateLinearMapping( Transform tr )
  97. {
  98. Vector3 direction = endPosition.position - startPosition.position;
  99. float length = direction.magnitude;
  100. direction.Normalize();
  101. Vector3 displacement = tr.position - startPosition.position;
  102. return Vector3.Dot( displacement, direction ) / length;
  103. }
  104. //-------------------------------------------------
  105. void Update()
  106. {
  107. if ( maintainMomemntum && mappingChangeRate != 0.0f )
  108. {
  109. //Dampen the mapping change rate and apply it to the mapping
  110. mappingChangeRate = Mathf.Lerp( mappingChangeRate, 0.0f, momemtumDampenRate * Time.deltaTime );
  111. linearMapping.value = Mathf.Clamp01( linearMapping.value + ( mappingChangeRate * Time.deltaTime ) );
  112. if ( repositionGameObject )
  113. {
  114. transform.position = Vector3.Lerp( startPosition.position, endPosition.position, linearMapping.value );
  115. }
  116. }
  117. }
  118. }
  119. }