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