A game about forced loneliness, made by TACStudios
at master 208 lines 8.7 kB view raw
1using System; 2using System.ComponentModel; 3using UnityEngine.InputSystem.Layouts; 4using UnityEngine.InputSystem.Utilities; 5 6#if UNITY_EDITOR 7using UnityEditor; 8using UnityEngine.InputSystem.Editor; 9using UnityEngine.UIElements; 10#endif 11 12namespace UnityEngine.InputSystem.Composites 13{ 14 /// <summary> 15 /// A 3D vector formed from six floating-point inputs. 16 /// </summary> 17 /// <remarks> 18 /// Depending on the setting of <see cref="mode"/>, the vector is either in the [-1..1] 19 /// range on each axis (normalized or not depending on <see cref="mode"/>) or is in the 20 /// full value range of the input controls. 21 /// 22 /// <example> 23 /// <code> 24 /// action.AddCompositeBinding("3DVector") 25 /// .With("Forward", "&lt;Keyboard&gt;/w") 26 /// .With("Backward", "&lt;Keyboard&gt;/s") 27 /// .With("Left", "&lt;Keyboard&gt;/a") 28 /// .With("Right", "&lt;Keyboard&gt;/d") 29 /// .With("Up", "&lt;Keyboard&gt;/q") 30 /// .With("Down", "&lt;Keyboard&gt;/e"); 31 /// </code> 32 /// </example> 33 /// </remarks> 34 /// <seealso cref="Vector2Composite"/> 35 [DisplayStringFormat("{up}+{down}/{left}+{right}/{forward}+{backward}")] 36 [DisplayName("Up/Down/Left/Right/Forward/Backward Composite")] 37 public class Vector3Composite : InputBindingComposite<Vector3> 38 { 39 /// <summary> 40 /// Binding for the button that represents the up (that is, <c>(0,1,0)</c>) direction of the vector. 41 /// </summary> 42 /// <remarks> 43 /// This property is automatically assigned by the input system. 44 /// </remarks> 45 // ReSharper disable once MemberCanBePrivate.Global 46 // ReSharper disable once FieldCanBeMadeReadOnly.Global 47 [InputControl(layout = "Axis")] public int up; 48 49 /// <summary> 50 /// Binding for the button that represents the down (that is, <c>(0,-1,0)</c>) direction of the vector. 51 /// </summary> 52 /// <remarks> 53 /// This property is automatically assigned by the input system. 54 /// </remarks> 55 // ReSharper disable once MemberCanBePrivate.Global 56 // ReSharper disable once FieldCanBeMadeReadOnly.Global 57 [InputControl(layout = "Axis")] public int down; 58 59 /// <summary> 60 /// Binding for the button that represents the left (that is, <c>(-1,0,0)</c>) direction of the vector. 61 /// </summary> 62 /// <remarks> 63 /// This property is automatically assigned by the input system. 64 /// </remarks> 65 // ReSharper disable once MemberCanBePrivate.Global 66 // ReSharper disable once FieldCanBeMadeReadOnly.Global 67 [InputControl(layout = "Axis")] public int left; 68 69 /// <summary> 70 /// Binding for the button that represents the right (that is, <c>(1,0,0)</c>) direction of the vector. 71 /// </summary> 72 /// <remarks> 73 /// This property is automatically assigned by the input system. 74 /// </remarks> 75 // ReSharper disable once MemberCanBePrivate.Global 76 // ReSharper disable once FieldCanBeMadeReadOnly.Global 77 [InputControl(layout = "Axis")] public int right; 78 79 /// <summary> 80 /// Binding for the button that represents the right (that is, <c>(0,0,1)</c>) direction of the vector. 81 /// </summary> 82 /// <remarks> 83 /// This property is automatically assigned by the input system. 84 /// </remarks> 85 // ReSharper disable once MemberCanBePrivate.Global 86 // ReSharper disable once FieldCanBeMadeReadOnly.Global 87 [InputControl(layout = "Axis")] public int forward; 88 89 /// <summary> 90 /// Binding for the button that represents the right (that is, <c>(0,0,-1)</c>) direction of the vector. 91 /// </summary> 92 /// <remarks> 93 /// This property is automatically assigned by the input system. 94 /// </remarks> 95 // ReSharper disable once MemberCanBePrivate.Global 96 // ReSharper disable once FieldCanBeMadeReadOnly.Global 97 [InputControl(layout = "Axis")] public int backward; 98 99 /// <summary> 100 /// How to synthesize a <c>Vector3</c> from the values read from <see cref="up"/>, <see cref="down"/>, 101 /// <see cref="left"/>, <see cref="right"/>, <see cref="forward"/>, and <see cref="backward"/>. 102 /// </summary> 103 /// <value>Determines how X, Y, and Z of the resulting <c>Vector3</c> are formed from input values.</value> 104 public Mode mode = Mode.Analog; 105 106 /// <inheritdoc/> 107 public override Vector3 ReadValue(ref InputBindingCompositeContext context) 108 { 109 if (mode == Mode.Analog) 110 { 111 var upValue = context.ReadValue<float>(up); 112 var downValue = context.ReadValue<float>(down); 113 var leftValue = context.ReadValue<float>(left); 114 var rightValue = context.ReadValue<float>(right); 115 var forwardValue = context.ReadValue<float>(forward); 116 var backwardValue = context.ReadValue<float>(backward); 117 118 return new Vector3(rightValue - leftValue, upValue - downValue, forwardValue - backwardValue); 119 } 120 else 121 { 122 var upValue = context.ReadValueAsButton(up) ? 1f : 0f; 123 var downValue = context.ReadValueAsButton(down) ? -1f : 0f; 124 var leftValue = context.ReadValueAsButton(left) ? -1f : 0f; 125 var rightValue = context.ReadValueAsButton(right) ? 1f : 0f; 126 var forwardValue = context.ReadValueAsButton(forward) ? 1f : 0f; 127 var backwardValue = context.ReadValueAsButton(backward) ? -1f : 0f; 128 129 var vector = new Vector3(leftValue + rightValue, upValue + downValue, forwardValue + backwardValue); 130 131 if (mode == Mode.DigitalNormalized) 132 vector = vector.normalized; 133 134 return vector; 135 } 136 } 137 138 /// <inheritdoc /> 139 public override float EvaluateMagnitude(ref InputBindingCompositeContext context) 140 { 141 var value = ReadValue(ref context); 142 return value.magnitude; 143 } 144 145 /// <summary> 146 /// Determines how a <c>Vector3</c> is synthesized from part controls. 147 /// </summary> 148 public enum Mode 149 { 150 /// <summary> 151 /// Part controls are treated as analog meaning that the floating-point values read from controls 152 /// will come through as is (minus the fact that the down and left direction values are negated). 153 /// </summary> 154 Analog, 155 156 /// <summary> 157 /// Part controls are treated as buttons (on/off) and the resulting vector is normalized. This means 158 /// that if, for example, both left and up are pressed, instead of returning a vector (-1,1,0), a vector 159 /// of roughly (-0.7,0.7,0) (that is, corresponding to <c>new Vector3(-1,1,0).normalized</c>) is returned instead. 160 /// </summary> 161 DigitalNormalized, 162 163 /// <summary> 164 /// Part controls are treated as buttons (on/off) and the resulting vector is not normalized. This means 165 /// that if both left and up are pressed, for example, the resulting vector is (-1,1,0) and has a length 166 /// greater than 1. 167 /// </summary> 168 Digital, 169 } 170 } 171 172 #if UNITY_EDITOR 173 internal class Vector3CompositeEditor : InputParameterEditor<Vector3Composite> 174 { 175 private GUIContent m_ModeLabel = new GUIContent("Mode", 176 "How to synthesize a Vector3 from the inputs. Digital " 177 + "treats part bindings as buttons (on/off) whereas Analog preserves " 178 + "floating-point magnitudes as read from controls."); 179 180 public override void OnGUI() 181 { 182#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS 183 if (!InputSystem.settings.IsFeatureEnabled(InputFeatureNames.kUseIMGUIEditorForAssets)) return; 184#endif 185 target.mode = (Vector3Composite.Mode)EditorGUILayout.EnumPopup(m_ModeLabel, target.mode); 186 } 187 188#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS 189 public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) 190 { 191 var modeField = new EnumField(m_ModeLabel.text, target.mode) 192 { 193 tooltip = m_ModeLabel.tooltip 194 }; 195 196 modeField.RegisterValueChangedCallback(evt => 197 { 198 target.mode = (Vector3Composite.Mode)evt.newValue; 199 onChangedCallback(); 200 }); 201 202 root.Add(modeField); 203 } 204 205#endif 206 } 207 #endif 208}