HoverButton.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. using UnityEngine.Events;
  9. namespace Valve.VR.InteractionSystem
  10. {
  11. //-------------------------------------------------------------------------
  12. [RequireComponent(typeof(Interactable))]
  13. public class HoverButton : MonoBehaviour
  14. {
  15. public Transform movingPart;
  16. public Vector3 localMoveDistance = new Vector3(0, -0.1f, 0);
  17. [Range(0, 1)]
  18. public float engageAtPercent = 0.95f;
  19. [Range(0, 1)]
  20. public float disengageAtPercent = 0.9f;
  21. public HandEvent onButtonDown;
  22. public HandEvent onButtonUp;
  23. public HandEvent onButtonIsPressed;
  24. public bool engaged = false;
  25. public bool buttonDown = false;
  26. public bool buttonUp = false;
  27. private Vector3 startPosition;
  28. private Vector3 endPosition;
  29. private Vector3 handEnteredPosition;
  30. private bool hovering;
  31. private Hand lastHoveredHand;
  32. private void Start()
  33. {
  34. if (movingPart == null && this.transform.childCount > 0)
  35. movingPart = this.transform.GetChild(0);
  36. startPosition = movingPart.localPosition;
  37. endPosition = startPosition + localMoveDistance;
  38. handEnteredPosition = endPosition;
  39. }
  40. private void HandHoverUpdate(Hand hand)
  41. {
  42. hovering = true;
  43. lastHoveredHand = hand;
  44. bool wasEngaged = engaged;
  45. float currentDistance = Vector3.Distance(movingPart.parent.InverseTransformPoint(hand.transform.position), endPosition);
  46. float enteredDistance = Vector3.Distance(handEnteredPosition, endPosition);
  47. if (currentDistance > enteredDistance)
  48. {
  49. enteredDistance = currentDistance;
  50. handEnteredPosition = movingPart.parent.InverseTransformPoint(hand.transform.position);
  51. }
  52. float distanceDifference = enteredDistance - currentDistance;
  53. float lerp = Mathf.InverseLerp(0, localMoveDistance.magnitude, distanceDifference);
  54. if (lerp > engageAtPercent)
  55. engaged = true;
  56. else if (lerp < disengageAtPercent)
  57. engaged = false;
  58. movingPart.localPosition = Vector3.Lerp(startPosition, endPosition, lerp);
  59. InvokeEvents(wasEngaged, engaged);
  60. }
  61. private void LateUpdate()
  62. {
  63. if (hovering == false)
  64. {
  65. movingPart.localPosition = startPosition;
  66. handEnteredPosition = endPosition;
  67. InvokeEvents(engaged, false);
  68. engaged = false;
  69. }
  70. hovering = false;
  71. }
  72. private void InvokeEvents(bool wasEngaged, bool isEngaged)
  73. {
  74. buttonDown = wasEngaged == false && isEngaged == true;
  75. buttonUp = wasEngaged == true && isEngaged == false;
  76. if (buttonDown && onButtonDown != null)
  77. onButtonDown.Invoke(lastHoveredHand);
  78. if (buttonUp && onButtonUp != null)
  79. onButtonUp.Invoke(lastHoveredHand);
  80. if (isEngaged && onButtonIsPressed != null)
  81. onButtonIsPressed.Invoke(lastHoveredHand);
  82. }
  83. }
  84. }