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