暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ButtonWithOneModifier.cs 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using System.ComponentModel;
  2. using UnityEngine.InputSystem.Layouts;
  3. using UnityEngine.InputSystem.Utilities;
  4. using UnityEngine.Scripting;
  5. ////TODO: remove this once we can break the API
  6. namespace UnityEngine.InputSystem.Composites
  7. {
  8. /// <summary>
  9. /// A button with an additional modifier. The button only triggers when
  10. /// the modifier is pressed.
  11. /// </summary>
  12. /// <remarks>
  13. /// This composite can be used to require another button to be held while
  14. /// pressing the button that triggers the action. This is most commonly used
  15. /// on keyboards to require one of the modifier keys (shift, ctrl, or alt)
  16. /// to be held in combination with another key, e.g. "CTRL+1".
  17. ///
  18. /// <example>
  19. /// <code>
  20. /// // Create a button action that triggers when CTRL+1
  21. /// // is pressed on the keyboard.
  22. /// var action = new InputAction(type: InputActionType.Button);
  23. /// action.AddCompositeBinding("ButtonWithOneModifier")
  24. /// .With("Modifier", "&lt;Keyboard&gt;/leftCtrl")
  25. /// .With("Modifier", "&lt;Keyboard&gt;/rightControl")
  26. /// .With("Button", "&lt;Keyboard&gt;/1")
  27. /// </code>
  28. /// </example>
  29. ///
  30. /// Note that this is not restricted to the keyboard and will preserve
  31. /// the full value of the button.
  32. ///
  33. /// <example>
  34. /// <code>
  35. /// // Create a button action that requires the A button on the
  36. /// // gamepad to be held and will then trigger from the gamepad's
  37. /// // left trigger button.
  38. /// var action = new InputAction(type: InputActionType.Button);
  39. /// action.AddCompositeBinding("ButtonWithOneModifier")
  40. /// .With("Modifier", "&lt;Gamepad&gt;/buttonSouth")
  41. /// .With("Button", "&lt;Gamepad&gt;/leftTrigger");
  42. /// </code>
  43. /// </example>
  44. /// </remarks>
  45. /// <seealso cref="ButtonWithTwoModifiers"/>
  46. [DesignTimeVisible(false)] // Obsoleted by OneModifierComposite
  47. [DisplayStringFormat("{modifier}+{button}")]
  48. public class ButtonWithOneModifier : InputBindingComposite<float>
  49. {
  50. /// <summary>
  51. /// Binding for the button that acts as a modifier, e.g. <c>&lt;Keyboard/leftCtrl</c>.
  52. /// </summary>
  53. /// <value>Part index to use with <see cref="InputBindingCompositeContext.ReadValue{T}(int)"/>.</value>
  54. /// <remarks>
  55. /// This property is automatically assigned by the input system.
  56. /// </remarks>
  57. // ReSharper disable once MemberCanBePrivate.Global
  58. // ReSharper disable once FieldCanBeMadeReadOnly.Global
  59. // ReSharper disable once UnassignedField.Global
  60. [InputControl(layout = "Button")] public int modifier;
  61. /// <summary>
  62. /// Binding for the button that is gated by the modifier. The composite will assume the value
  63. /// of this button while the modifier is pressed.
  64. /// </summary>
  65. /// <value>Part index to use with <see cref="InputBindingCompositeContext.ReadValue{T}(int)"/>.</value>
  66. /// <remarks>
  67. /// This property is automatically assigned by the input system.
  68. /// </remarks>
  69. // ReSharper disable once MemberCanBePrivate.Global
  70. // ReSharper disable once FieldCanBeMadeReadOnly.Global
  71. // ReSharper disable once UnassignedField.Global
  72. [InputControl(layout = "Button")] public int button;
  73. /// <summary>
  74. /// If set to <c>true</c>, <see cref="modifier"/> can be pressed after <see cref="button"/> and the composite will
  75. /// still trigger. Default is false.
  76. /// </summary>
  77. /// <remarks>
  78. /// By default, <see cref="modifier"/> is required to be in pressed state before or at the same time that <see cref="button"/>
  79. /// goes into pressed state for the composite as a whole to trigger. This means that binding to, for example, <c>Shift+B</c>,
  80. /// the <c>shift</c> key has to be pressed before pressing the <c>B</c> key. This is the behavior usually expected with
  81. /// keyboard shortcuts.
  82. ///
  83. /// This parameter can be used to bypass this behavior and allow any timing between <see cref="modifier"/> and <see cref="button"/>.
  84. /// The only requirement is for them both to concurrently be in pressed state.
  85. /// </remarks>
  86. public bool overrideModifiersNeedToBePressedFirst;
  87. /// <summary>
  88. /// Return the value of the <see cref="button"/> part if <see cref="modifier"/> is pressed. Otherwise
  89. /// return 0.
  90. /// </summary>
  91. /// <param name="context">Evaluation context passed in from the input system.</param>
  92. /// <returns>The current value of the composite.</returns>
  93. public override float ReadValue(ref InputBindingCompositeContext context)
  94. {
  95. if (ModifierIsPressed(ref context))
  96. return context.ReadValue<float>(button);
  97. return default;
  98. }
  99. private bool ModifierIsPressed(ref InputBindingCompositeContext context)
  100. {
  101. var modifierDown = context.ReadValueAsButton(modifier);
  102. if (modifierDown && !overrideModifiersNeedToBePressedFirst)
  103. {
  104. var timestamp = context.GetPressTime(button);
  105. var timestamp1 = context.GetPressTime(modifier);
  106. return timestamp1 <= timestamp;
  107. }
  108. return modifierDown;
  109. }
  110. /// <summary>
  111. /// Same as <see cref="ReadValue"/> in this case.
  112. /// </summary>
  113. /// <param name="context">Evaluation context passed in from the input system.</param>
  114. /// <returns>A >0 value if the composite is currently actuated.</returns>
  115. public override float EvaluateMagnitude(ref InputBindingCompositeContext context)
  116. {
  117. return ReadValue(ref context);
  118. }
  119. protected override void FinishSetup(ref InputBindingCompositeContext context)
  120. {
  121. if (!overrideModifiersNeedToBePressedFirst)
  122. overrideModifiersNeedToBePressedFirst = !InputSystem.settings.shortcutKeysConsumeInput;
  123. }
  124. }
  125. }