暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

HoldInteraction.cs 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using System;
  2. using System.ComponentModel;
  3. using UnityEngine.InputSystem.Controls;
  4. using UnityEngine.Scripting;
  5. #if UNITY_EDITOR
  6. using UnityEngine.InputSystem.Editor;
  7. using UnityEngine.UIElements;
  8. #endif
  9. namespace UnityEngine.InputSystem.Interactions
  10. {
  11. /// <summary>
  12. /// Performs the action if the control is pressed and held for at least the
  13. /// set duration (which defaults to <see cref="InputSettings.defaultHoldTime"/>).
  14. /// </summary>
  15. /// <remarks>
  16. /// The action is started when the control is pressed. If the control is released before the
  17. /// set <see cref="duration"/>, the action is canceled. As soon as the hold time is reached,
  18. /// the action performs. The action then stays performed until the control is released, at
  19. /// which point the action cancels.
  20. ///
  21. /// <example>
  22. /// <code>
  23. /// // Action that requires A button on gamepad to be held for half a second.
  24. /// var action = new InputAction(binding: "&lt;Gamepad&gt;/buttonSouth", interactions: "hold(duration=0.5)");
  25. /// </code>
  26. /// </example>
  27. /// </remarks>
  28. [DisplayName("Hold")]
  29. public class HoldInteraction : IInputInteraction
  30. {
  31. /// <summary>
  32. /// Duration in seconds that the control must be pressed for the hold to register.
  33. /// </summary>
  34. /// <remarks>
  35. /// If this is less than or equal to 0 (the default), <see cref="InputSettings.defaultHoldTime"/> is used.
  36. ///
  37. /// Duration is expressed in real time and measured against the timestamps of input events
  38. /// (<see cref="LowLevel.InputEvent.time"/>) not against game time (<see cref="Time.time"/>).
  39. /// </remarks>
  40. public float duration;
  41. /// <summary>
  42. /// Magnitude threshold that must be crossed by an actuated control for the control to
  43. /// be considered pressed.
  44. /// </summary>
  45. /// <remarks>
  46. /// If this is less than or equal to 0 (the default), <see cref="InputSettings.defaultButtonPressPoint"/> is used instead.
  47. /// </remarks>
  48. /// <seealso cref="InputControl.EvaluateMagnitude()"/>
  49. public float pressPoint;
  50. private float durationOrDefault => duration > 0.0 ? duration : InputSystem.settings.defaultHoldTime;
  51. private float pressPointOrDefault => pressPoint > 0.0 ? pressPoint : ButtonControl.s_GlobalDefaultButtonPressPoint;
  52. private double m_TimePressed;
  53. /// <inheritdoc />
  54. public void Process(ref InputInteractionContext context)
  55. {
  56. if (context.timerHasExpired)
  57. {
  58. context.PerformedAndStayPerformed();
  59. return;
  60. }
  61. switch (context.phase)
  62. {
  63. case InputActionPhase.Waiting:
  64. if (context.ControlIsActuated(pressPointOrDefault))
  65. {
  66. m_TimePressed = context.time;
  67. context.Started();
  68. context.SetTimeout(durationOrDefault);
  69. }
  70. break;
  71. case InputActionPhase.Started:
  72. // If we've reached our hold time threshold, perform the hold.
  73. // We do this regardless of what state the control changed to.
  74. if (context.time - m_TimePressed >= durationOrDefault)
  75. {
  76. context.PerformedAndStayPerformed();
  77. }
  78. if (!context.ControlIsActuated())
  79. {
  80. // Control is no longer actuated so we're done.
  81. context.Canceled();
  82. }
  83. break;
  84. case InputActionPhase.Performed:
  85. if (!context.ControlIsActuated(pressPointOrDefault))
  86. context.Canceled();
  87. break;
  88. }
  89. }
  90. /// <inheritdoc />
  91. public void Reset()
  92. {
  93. m_TimePressed = 0;
  94. }
  95. }
  96. #if UNITY_EDITOR
  97. /// <summary>
  98. /// UI that is displayed when editing <see cref="HoldInteraction"/> in the editor.
  99. /// </summary>
  100. internal class HoldInteractionEditor : InputParameterEditor<HoldInteraction>
  101. {
  102. protected override void OnEnable()
  103. {
  104. m_PressPointSetting.Initialize("Press Point",
  105. "Float value that an axis control has to cross for it to be considered pressed.",
  106. "Default Button Press Point",
  107. () => target.pressPoint, v => target.pressPoint = v, () => ButtonControl.s_GlobalDefaultButtonPressPoint);
  108. m_DurationSetting.Initialize("Hold Time",
  109. "Time (in seconds) that a control has to be held in order for it to register as a hold.",
  110. "Default Hold Time",
  111. () => target.duration, x => target.duration = x, () => InputSystem.settings.defaultHoldTime);
  112. }
  113. public override void OnGUI()
  114. {
  115. m_PressPointSetting.OnGUI();
  116. m_DurationSetting.OnGUI();
  117. }
  118. #if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
  119. public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback)
  120. {
  121. m_PressPointSetting.OnDrawVisualElements(root, onChangedCallback);
  122. m_DurationSetting.OnDrawVisualElements(root, onChangedCallback);
  123. }
  124. #endif
  125. private CustomOrDefaultSetting m_PressPointSetting;
  126. private CustomOrDefaultSetting m_DurationSetting;
  127. }
  128. #endif
  129. }