Example #1
0
            public static void Process(InputRemoting receiver, Message msg)
            {
                var senderIndex = receiver.FindOrCreateSenderRecord(msg.participantId);

                // Remove devices added by remote.
                var devices = receiver.m_Senders[senderIndex].devices;

                if (devices != null)
                {
                    foreach (var remoteDevice in devices)
                    {
                        var device = receiver.m_LocalManager.TryGetDeviceById(remoteDevice.localId);
                        if (device != null)
                        {
                            receiver.m_LocalManager.RemoveDevice(device);
                        }
                    }
                }

                ////TODO: remove layouts added by remote

                ArrayHelpers.EraseAt(ref receiver.m_Senders, senderIndex);

                ////TODO: stop sending if last remote disconnects and StartSendingOnConnect is active
            }
        public void OnPostprocessBuild(BuildReport report)
        {
            if (m_SettingsAddedToPreloadedAssets == null)
            {
                return;
            }

            var wasDirty = IsPlayerSettingsDirty();

            // Revert back to original state.
            var preloadedAssets = PlayerSettings.GetPreloadedAssets();
            var index           = preloadedAssets.IndexOfReference <Object, Object>(m_SettingsAddedToPreloadedAssets);

            if (index != -1)
            {
                ArrayHelpers.EraseAt(ref preloadedAssets, index);
                PlayerSettings.SetPreloadedAssets(preloadedAssets);
            }
            m_SettingsAddedToPreloadedAssets = null;

            if (!wasDirty)
            {
                ClearPlayerSettingsDirtyFlag();
            }
        }
Example #3
0
            private void InitializeModifierListView()
            {
                m_ModifierListView = new ReorderableList(m_Modifiers, typeof(InputTemplate.NameAndParameters));

                m_ModifierListView.drawHeaderCallback =
                    (rect) => EditorGUI.LabelField(rect, Contents.modifiers);

                m_ModifierListView.drawElementCallback =
                    (rect, index, isActive, isFocused) =>
                {
                    ////TODO: parameters
                    EditorGUI.LabelField(rect, m_Modifiers[index].name);
                };

                m_ModifierListView.onAddDropdownCallback =
                    (rect, list) =>
                {
                    var menu = new GenericMenu();
                    for (var i = 0; i < m_ModifierChoices.Length; ++i)
                    {
                        menu.AddItem(m_ModifierChoices[i], false, AddModifier, m_ModifierChoices[i].text);
                    }
                    menu.ShowAsContext();
                };

                m_ModifierListView.onRemoveCallback =
                    (list) =>
                {
                    ArrayHelpers.EraseAt(ref m_Modifiers, list.index);
                    ApplyModifiers();
                };
            }
        private void OnDeleteControlScheme()
        {
            Debug.Assert(m_SelectedControlSchemeIndex >= 0, "Control scheme must be selected");

            var name         = m_ControlSchemes[m_SelectedControlSchemeIndex].name;
            var bindingGroup = m_ControlSchemes[m_SelectedControlSchemeIndex].bindingGroup;

            // Ask for confirmation.
            if (!EditorUtility.DisplayDialog("Delete scheme?", $"Do you want to delete control scheme '{name}'?",
                                             "Delete", "Cancel"))
            {
                return;
            }

            ArrayHelpers.EraseAt(ref m_ControlSchemes, m_SelectedControlSchemeIndex);
            m_SelectedControlSchemeIndex           = -1;
            m_SelectedSchemeDeviceRequirementNames = null;

            if (m_SelectedDeviceRequirementIndex >= 0)
            {
                m_SelectedDeviceRequirementIndex = -1;
                onSelectedDeviceChanged?.Invoke();
            }

            onControlSchemesChanged?.Invoke();
            onSelectedSchemeChanged?.Invoke();
            onControlSchemeDeleted?.Invoke(name, bindingGroup);
        }
Example #5
0
 public void OnGUI()
 {
     if (m_EditableParametersForEachListItem == null || m_EditableParametersForEachListItem.Length == 0)
     {
         using (var scope = new EditorGUI.DisabledScope(true))
         {
             EditorGUI.indentLevel++;
             EditorGUILayout.LabelField($"No {itemName}s have been added.");
             EditorGUI.indentLevel--;
         }
     }
     else
     {
         for (var i = 0; i < m_EditableParametersForEachListItem.Length; i++)
         {
             var editableParams = m_EditableParametersForEachListItem[i];
             EditorGUILayout.BeginHorizontal();
             if (editableParams.hasUIToShow)
             {
                 editableParams.visible = EditorGUILayout.Foldout(editableParams.visible, editableParams.name, Styles.s_FoldoutStyle);
             }
             else
             {
                 GUILayout.Space(16);
                 EditorGUILayout.LabelField(editableParams.name, EditorStyles.boldLabel);
             }
             GUILayout.FlexibleSpace();
             using (var scope = new EditorGUI.DisabledScope(i == 0))
             {
                 if (GUILayout.Button(m_UpButton, Styles.s_UpDownButtonStyle))
                 {
                     SwapEntry(i, i - 1);
                 }
             }
             using (var scope = new EditorGUI.DisabledScope(i == m_EditableParametersForEachListItem.Length - 1))
             {
                 if (GUILayout.Button(m_DownButton, Styles.s_UpDownButtonStyle))
                 {
                     SwapEntry(i, i + 1);
                 }
             }
             if (GUILayout.Button(m_DeleteButton, EditorStyles.label))
             {
                 ArrayHelpers.EraseAt(ref m_ParametersForEachListItem, i);
                 ArrayHelpers.EraseAt(ref m_EditableParametersForEachListItem, i);
                 m_Apply();
                 GUIUtility.ExitGUI();
             }
             EditorGUILayout.EndHorizontal();
             if (editableParams.visible)
             {
                 EditorGUI.indentLevel++;
                 editableParams.OnGUI();
                 EditorGUI.indentLevel--;
             }
             GUIHelpers.DrawLineSeparator();
         }
     }
 }
Example #6
0
        public void RemoveControlScheme(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            ArrayHelpers.EraseAt(ref m_ControlSchemes, GetControlSchemeIndex(name));
        }
        /// <summary>
        /// Remove the given action from its <see cref="InputActionMap"/>.
        /// </summary>
        /// <param name="action">An input action that is part of an <see cref="InputActionMap"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException"><paramref name="action"/> is part of an <see cref="InputActionMap"/>
        /// that has at least one enabled action -or- <paramref name="action"/> is a standalone action
        /// that is not part of an <see cref="InputActionMap"/> and thus cannot be removed from anything.</exception>
        /// <remarks>
        /// After removal, the action's <see cref="InputAction.actionMap"/> will be set to <c>null</c>
        /// and the action will effectively become a standalone action that is not associated with
        /// any action map. Bindings on the action will be preserved. On the action map, the bindings
        /// for the action will be removed.
        /// </remarks>
        /// <seealso cref="AddAction"/>
        public static void RemoveAction(this InputAction action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            var actionMap = action.actionMap;

            if (actionMap == null)
            {
                throw new ArgumentException(
                          $"Action '{action}' does not belong to an action map; nowhere to remove from", nameof(action));
            }
            if (actionMap.enabled)
            {
                throw new ArgumentException($"Cannot remove action '{action}' while its action map is enabled");
            }

            var bindingsForAction = action.bindings.ToArray();

            var index = ArrayHelpers.IndexOfReference(actionMap.m_Actions, action);

            Debug.Assert(index != -1, "Could not find action in map");
            ArrayHelpers.EraseAt(ref actionMap.m_Actions, index);

            action.m_ActionMap = null;
            action.m_SingletonActionBindings = bindingsForAction;

            actionMap.ClearPerActionCachedBindingData();

            // Remove bindings to action from map.
            var newActionMapBindingCount = actionMap.m_Bindings.Length - bindingsForAction.Length;

            if (newActionMapBindingCount == 0)
            {
                actionMap.m_Bindings = null;
            }
            else
            {
                var newActionMapBindings = new InputBinding[newActionMapBindingCount];
                var oldActionMapBindings = actionMap.m_Bindings;
                var bindingIndex         = 0;
                for (var i = 0; i < oldActionMapBindings.Length; ++i)
                {
                    var binding = oldActionMapBindings[i];
                    if (bindingsForAction.IndexOf(b => b == binding) == -1)
                    {
                        newActionMapBindings[bindingIndex++] = binding;
                    }
                }
                actionMap.m_Bindings = newActionMapBindings;
            }
        }
            public void Erase()
            {
                ArrayHelpers.EraseAt(ref m_ActionMap.m_Bindings, m_BindingIndex);
                m_ActionMap.ClearPerActionCachedBindingData();

                // We have switched to a different binding array. For singleton actions, we need to
                // sync up the reference that the action itself has.
                if (m_ActionMap.m_SingletonAction != null)
                {
                    m_ActionMap.m_SingletonAction.m_SingletonActionBindings = m_ActionMap.m_Bindings;
                }
            }
        private void OnDisconnected(int id)
        {
            if (m_ConnectedIds == null || !ArrayHelpers.Contains(m_ConnectedIds, id))
            {
                return;
            }

            ArrayHelpers.EraseAt(ref m_ConnectedIds, id);

            SendToSubscribers(InputRemoting.MessageType.Disconnect, new MessageEventArgs {
                playerId = id
            });
        }
Example #10
0
        protected PropertiesReorderableList(SerializedProperty property, Action applyAction)
        {
            m_Property    = property;
            m_Apply       = applyAction;
            m_ListItems   = new List <string>();
            m_ListOptions = GetOptions();
            m_EditableParametersForSelectedItem = new ParameterListView {
                onChange = OnParametersChanged
            };
            m_ParametersForEachListItem = InputControlLayout.ParseNameAndParameterList(m_Property.stringValue)
                                          ?? new InputControlLayout.NameAndParameters[0];

            foreach (var nameAndParams in m_ParametersForEachListItem)
            {
                m_ListItems.Add(nameAndParams.name);
            }

            m_ListView = new ReorderableList(m_ListItems, typeof(string))
            {
                headerHeight          = 3,
                onAddDropdownCallback = (rect, list) =>
                {
                    var menu = new GenericMenu();
                    foreach (var name in m_ListOptions.names)
                    {
                        menu.AddItem(new GUIContent(name), false, OnAddElement, name);
                    }
                    menu.ShowAsContext();
                },
                onRemoveCallback = list =>
                {
                    var index = list.index;
                    list.list.RemoveAt(index);
                    ArrayHelpers.EraseAt(ref m_ParametersForEachListItem, index);
                    m_EditableParametersForSelectedItem.Clear();
                    m_Apply();
                    list.index = -1;
                },
                onReorderCallbackWithDetails = (list, oldIndex, newIndex) =>
                {
                    MemoryHelpers.Swap(ref m_ParametersForEachListItem[oldIndex],
                                       ref m_ParametersForEachListItem[newIndex]);
                    OnSelection(list);
                    m_Apply();
                },
                onSelectCallback = OnSelection
            };
        }
        /// <summary>
        /// Remove the control scheme with the given name from the asset.
        /// </summary>
        /// <param name="asset">Asset to remove the control scheme from.</param>
        /// <param name="name">Name of the control scheme. Matching is case-insensitive.</param>
        /// <exception cref="ArgumentNullException"><paramref name="asset"/> is null -or- <paramref name="name"/>
        /// is <c>null</c> or empty.</exception>
        /// <remarks>
        /// If no control scheme with the given name can be found, the method does nothing.
        /// </remarks>
        public static void RemoveControlScheme(this InputActionAsset asset, string name)
        {
            if (asset == null)
            {
                throw new ArgumentNullException(nameof(asset));
            }
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            var index = asset.FindControlSchemeIndex(name);

            if (index != -1)
            {
                ArrayHelpers.EraseAt(ref asset.m_ControlSchemes, index);
            }
        }
            private void InitializeInteractionListView()
            {
                m_InteractionListView = new ReorderableList(m_Interactions, typeof(InputControlLayout.NameAndParameters));

                m_InteractionListView.drawHeaderCallback =
                    rect => EditorGUI.LabelField(rect, Contents.interactions);

                m_InteractionListView.drawElementCallback =
                    (rect, index, isActive, isFocused) =>
                {
                    ////TODO: parameters
                    EditorGUI.LabelField(rect, m_Interactions[index].name);
                };

                m_InteractionListView.onAddDropdownCallback =
                    (rect, list) =>
                {
                    var menu = new GenericMenu();
                    for (var i = 0; i < m_InteractionChoices.Length; ++i)
                    {
                        menu.AddItem(m_InteractionChoices[i], false, AddInteraction, m_InteractionChoices[i].text);
                    }
                    menu.ShowAsContext();
                };

                m_InteractionListView.onRemoveCallback =
                    (list) =>
                {
                    var indexToRemove = list.index;
                    if (indexToRemove == m_Interactions.Length - 1)
                    {
                        --list.index;
                    }
                    ArrayHelpers.EraseAt(ref m_Interactions, indexToRemove);
                    if (m_Interactions == null)
                    {
                        m_Interactions = new InputControlLayout.NameAndParameters[0];
                    }
                    list.list = m_Interactions;
                    ApplyInteractions();
                };
            }
Example #13
0
        public void RemoveRemoteDevices(int participantId)
        {
            var senderIndex = FindOrCreateSenderRecord(participantId);

            // Remove devices added by remote.
            var devices = m_Senders[senderIndex].devices;

            if (devices != null)
            {
                foreach (var remoteDevice in devices)
                {
                    var device = m_LocalManager.TryGetDeviceById(remoteDevice.localId);
                    if (device != null)
                    {
                        m_LocalManager.RemoveDevice(device);
                    }
                }
            }

            ////TODO: remove layouts added by remote

            ArrayHelpers.EraseAt(ref m_Senders, senderIndex);
        }
        public static void ReplaceBindingGroup(SerializedObject asset, string oldBindingGroup, string newBindingGroup, bool deleteOrphanedBindings = false)
        {
            var mapArrayProperty = asset.FindProperty("m_ActionMaps");
            var mapCount         = mapArrayProperty.arraySize;

            for (var k = 0; k < mapCount; ++k)
            {
                var actionMapProperty     = mapArrayProperty.GetArrayElementAtIndex(k);
                var bindingsArrayProperty = actionMapProperty.FindPropertyRelative("m_Bindings");
                var bindingsCount         = bindingsArrayProperty.arraySize;

                for (var i = 0; i < bindingsCount; ++i)
                {
                    var bindingProperty = bindingsArrayProperty.GetArrayElementAtIndex(i);
                    var groupsProperty  = bindingProperty.FindPropertyRelative("m_Groups");
                    var groups          = groupsProperty.stringValue;

                    // Ignore bindings not belonging to any control scheme.
                    if (string.IsNullOrEmpty(groups))
                    {
                        continue;
                    }

                    var groupsArray = groups.Split(InputBinding.Separator);
                    var numGroups   = groupsArray.LengthSafe();
                    var didRename   = false;
                    for (var n = 0; n < numGroups; ++n)
                    {
                        if (string.Compare(groupsArray[n], oldBindingGroup, StringComparison.InvariantCultureIgnoreCase) != 0)
                        {
                            continue;
                        }
                        if (string.IsNullOrEmpty(newBindingGroup))
                        {
                            ArrayHelpers.EraseAt(ref groupsArray, n);
                            --n;
                            --numGroups;
                        }
                        else
                        {
                            groupsArray[n] = newBindingGroup;
                        }
                        didRename = true;
                    }
                    if (!didRename)
                    {
                        continue;
                    }

                    if (groupsArray != null)
                    {
                        groupsProperty.stringValue = string.Join(InputBinding.kSeparatorString, groupsArray);
                    }
                    else
                    {
                        if (deleteOrphanedBindings)
                        {
                            // Binding no long belongs to any binding group. Delete it.
                            bindingsArrayProperty.DeleteArrayElementAtIndex(i);
                            --i;
                            --bindingsCount;
                        }
                        else
                        {
                            groupsProperty.stringValue = string.Empty;
                        }
                    }
                }
            }
        }
        public override void OnGUI(string searchContext)
        {
            if (m_Settings == null)
            {
                InitializeWithCurrentSettings();
            }

            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);

            var selectedSettingsAsset = EditorGUILayout.Popup(m_CurrentSelectedInputSettingsAsset,
                                                              m_AvailableSettingsAssetsOptions, EditorStyles.toolbarPopup);

            if (selectedSettingsAsset != m_CurrentSelectedInputSettingsAsset)
            {
                // If we selected an asset and the current settings are not coming from an asset,
                // remove the "<No Asset>" entry we added to the dropdown.
                if (selectedSettingsAsset != 0 && m_AvailableInputSettingsAssets[m_CurrentSelectedInputSettingsAsset] == "<No Asset>")
                {
                    ArrayHelpers.EraseAt(ref m_AvailableInputSettingsAssets, m_CurrentSelectedInputSettingsAsset);
                }

                m_CurrentSelectedInputSettingsAsset = selectedSettingsAsset;
                var settings =
                    AssetDatabase.LoadAssetAtPath <InputSettings>(
                        m_AvailableInputSettingsAssets[selectedSettingsAsset]);

                // Install. This will automatically cause us to re-initialize through InputSystem.onSettingsChange.
                InputSystem.settings = settings;
            }

            // Style can only be initialized after skin has been initialized. Settings providers are
            // pulled up earlier than that so we do it lazily from here.
            if (m_NewAssetButtonStyle == null)
            {
                m_NewAssetButtonStyle            = new GUIStyle("toolbarButton");
                m_NewAssetButtonStyle.fixedWidth = 40;
            }

            if (GUILayout.Button(m_NewAssetButtonText, m_NewAssetButtonStyle))
            {
                CreateNewSettingsAsset();
            }

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            if (m_AvailableInputSettingsAssets[m_CurrentSelectedInputSettingsAsset] == "<No Asset>")
            {
                EditorGUILayout.HelpBox("Input settings can only be edited when stored in an asset.\n\n"
                                        + "Choose an existing asset (if any) from the dropdown or create a new asset by pressing the 'New' button. "
                                        + "Input settings can be placed anywhere in your project.",
                                        MessageType.Info);
            }

            EditorGUILayout.HelpBox(
                "Please note that the new input system is still under development and not all features are fully functional or stable yet.\n\n"
                + "For more information, visit https://github.com/Unity-Technologies/InputSystem or https://forum.unity.com/forums/new-input-system.103/.",
                MessageType.Warning);

            EditorGUILayout.Space();
            EditorGUILayout.Separator();
            EditorGUILayout.Space();

            Debug.Assert(m_Settings != null);

            EditorGUI.BeginChangeCheck();

            EditorGUILayout.PropertyField(m_UpdateMode);
            var updateMode = (InputSettings.UpdateMode)m_UpdateMode.intValue;

            if (updateMode == InputSettings.UpdateMode.ProcessEventsInBothFixedAndDynamicUpdate)
            {
                // Choosing action update mode only makes sense if we have an ambiguous situation, i.e.
                // when we have both dynamic and fixed updates in the picture.
                ////TODO: enable when action update mode is properly sorted
                //EditorGUILayout.PropertyField(m_ActionUpdateMode);
            }

            ////TODO: enable when backported
            //EditorGUILayout.PropertyField(m_TimesliceEvents);

            EditorGUILayout.PropertyField(m_RunInBackground);
            EditorGUILayout.PropertyField(m_FilterNoiseOnCurrent);
            EditorGUILayout.PropertyField(m_CompensateForScreenOrientation);

            EditorGUILayout.Space();
            EditorGUILayout.Separator();
            EditorGUILayout.Space();

            EditorGUILayout.PropertyField(m_DefaultDeadzoneMin);
            EditorGUILayout.PropertyField(m_DefaultDeadzoneMax);
            EditorGUILayout.PropertyField(m_DefaultButtonPressPoint);
            EditorGUILayout.PropertyField(m_DefaultTapTime);
            EditorGUILayout.PropertyField(m_DefaultSlowTapTime);
            EditorGUILayout.PropertyField(m_DefaultHoldTime);

            EditorGUILayout.Space();
            EditorGUILayout.Separator();
            EditorGUILayout.Space();

            EditorGUILayout.HelpBox("Leave 'Supported Devices' empty if you want the input system to support all input devices it can recognize. If, however, "
                                    + "you are only interested in a certain set of devices, adding them here will narrow the scope of what's presented in the editor "
                                    + "and avoid picking up input from devices not relevant to the project.", MessageType.None);

            m_SupportedDevices.DoLayoutList();

            if (EditorGUI.EndChangeCheck())
            {
                Apply();
            }
        }
Example #16
0
        protected PropertiesReorderableList(SerializedProperty property, Action applyAction, string expectedControlLayout)
        {
            m_Property    = property;
            m_Apply       = applyAction;
            m_ListItems   = new List <string>();
            m_ListOptions = GetOptions();
            m_EditableParametersForSelectedItem = new ParameterListView {
                onChange = OnParametersChanged
            };
            m_ParametersForEachListItem = InputControlLayout.ParseNameAndParameterList(m_Property.stringValue)
                                          ?? new InputControlLayout.NameAndParameters[0];
            m_ExpectedControlLayout = expectedControlLayout;

            foreach (var nameAndParams in m_ParametersForEachListItem)
            {
                var name = ObjectNames.NicifyVariableName(nameAndParams.name);

                ////REVIEW: finding this kind of stuff should probably have better support globally on the asset; e.g. some
                ////        notification that pops up and allows fixing all occurrences in one click
                // Find out if we still support this option and indicate it in the list, if we don't.
                if (m_ListOptions.LookupTypeRegistration(new InternedString(nameAndParams.name)) == null)
                {
                    name += " (Obsolete)";
                }

                m_ListItems.Add(name);
            }

            m_ListView = new ReorderableList(m_ListItems, typeof(string))
            {
                headerHeight          = 3,
                onAddDropdownCallback = (rect, list) =>
                {
                    Type expectedValueType = null;
                    if (!string.IsNullOrEmpty(m_ExpectedControlLayout))
                    {
                        expectedValueType = EditorInputControlLayoutCache.GetValueType(m_ExpectedControlLayout);
                    }

                    // Add only original names to the menu and not aliases.
                    var menu = new GenericMenu();
                    foreach (var name in m_ListOptions.internedNames.Where(x => !m_ListOptions.aliases.Contains(x)).OrderBy(x => x.ToString()))
                    {
                        // Skip if not compatible with value type.
                        if (expectedValueType != null)
                        {
                            var type      = m_ListOptions.LookupTypeRegistration(name);
                            var valueType = GetValueType(type);
                            if (valueType != null && !expectedValueType.IsAssignableFrom(valueType))
                            {
                                continue;
                            }
                        }

                        var niceName = ObjectNames.NicifyVariableName(name);
                        menu.AddItem(new GUIContent(niceName), false, OnAddElement, name.ToString());
                    }
                    menu.ShowAsContext();
                },
                onRemoveCallback = list =>
                {
                    var index = list.index;
                    list.list.RemoveAt(index);
                    ArrayHelpers.EraseAt(ref m_ParametersForEachListItem, index);
                    m_EditableParametersForSelectedItem.Clear();
                    m_Apply();
                    list.index = -1;
                },
                onReorderCallbackWithDetails = (list, oldIndex, newIndex) =>
                {
                    MemoryHelpers.Swap(ref m_ParametersForEachListItem[oldIndex],
                                       ref m_ParametersForEachListItem[newIndex]);
                    OnSelection(list);
                    m_Apply();
                },
                onSelectCallback = OnSelection
            };
        }