public object Clone() { var clone = new ControlScheme(); clone.m_Name = m_Name; clone.m_DeviceSlots = m_DeviceSlots.SemiDeepClone(); clone.m_ActionMap = m_ActionMap; clone.m_Bindings = m_Bindings.SemiDeepClone(); // Don't clone customized flag. return(clone); }
public override string GetSourceName(ControlScheme controlScheme, bool forceStandardized) { if (sourceControl != null && !forceStandardized) { return(sourceControl.sourceName); } SupportedControl supported = supportedControl; if (supported.Equals(SupportedControl.None)) { return("Unassigned"); } return(supported.standardName); }
public override string GetSourceName(ControlScheme controlScheme, bool forceStandardized) { if (sources == null || sources.Count == 0) { return("None"); } string str = sources[0].GetSourceName(controlScheme, forceStandardized); for (int i = 1; i < sources.Count; i++) { str = string.Format("{0} / {1}", str, sources[i].GetSourceName(controlScheme, forceStandardized)); } return(str); }
public override string GetSourceName(ControlScheme controlScheme, bool forceStandardized) { if (main == null) { return("None"); } string str = main.GetSourceName(controlScheme, forceStandardized); for (int i = modifiers.Count - 1; i >= 0; i--) { if (modifiers[i] != null) { str = modifiers[i].GetSourceName(controlScheme, forceStandardized) + " + " + str; } } return(str); }
private void Assign(ControlScheme controlScheme, List <InputDevice> devices) { m_ControlScheme = controlScheme; // Create state for every device. var deviceStates = new List <InputState>(); for (int i = 0; i < devices.Count; i++) { var device = devices[i]; deviceStates.Add(new InputState(device, GetClonedControlsList(device))); } m_DeviceStates = deviceStates; m_ControlScheme.Initialize(this); RefreshBindings(); if (onStatusChanged != null) { onStatusChanged(); } }
/// <summary> /// Find the best control scheme for the available devices and initialize the action map input. /// </summary> /// <param name="availableDevices">Available devices in the system</param> /// <param name="requiredDevice">Required device for scheme</param> /// <returns></returns> public bool TryInitializeWithDevices(List <InputDevice> availableDevices, List <InputDevice> requiredDevices = null, int requiredControlSchemeIndex = -1) { int bestScheme = -1; List <InputDevice> bestFoundDevices = null; bool success = actionMap.CanInitializeInstanceWithDevices( availableDevices, out bestScheme, out bestFoundDevices, requiredDevices, requiredControlSchemeIndex); if (!success) { return(false); } ControlScheme matchingControlScheme = controlSchemes[bestScheme]; Assign(matchingControlScheme, bestFoundDevices); return(true); }
public void EnforceBindingsTypeConsistency() { for (int actionIndex = 0; actionIndex < actions.Count; actionIndex++) { var action = actions[actionIndex]; Type controlType = action.controlType; Type bindingType = null; if (controlType != null) { // InputControl > InputControl<T> // We know the selected type is RootBinding<T> or a derived type. // We want to find out what type the T is. // Getting first generic argument doesn't work if the selected type // is a non-generic class that derives from InputControl<T> (with a specific T) // rather than being InputControl<T> itself. // So we need to go down to the InputControl<T> base type first. Type currentType = controlType; while (currentType.BaseType != typeof(InputControl)) { currentType = currentType.BaseType; if (currentType == typeof(object)) { throw new Exception("Selected Control Type does not derive from InputControl"); } } Type genericArgumentType = currentType.GetGenericArguments()[0]; bindingType = typeof(RootBinding <, >).MakeGenericType(new System.Type[] { controlType, genericArgumentType }); } // Scheme bindings. for (int schemeIndex = 0; schemeIndex < controlSchemes.Count; schemeIndex++) { ControlScheme scheme = controlSchemes[schemeIndex]; if (scheme.bindings.Count <= actionIndex) { if (bindingType == null || action.combined) { scheme.bindings.Add(null); } else { scheme.bindings.Add(CreateBinding(bindingType, controlType)); } } else if (((scheme.bindings[actionIndex] == null) != (bindingType == null || action.combined)) || (scheme.bindings[actionIndex] != null && scheme.bindings[actionIndex].GetType() != bindingType)) { if (bindingType == null || action.combined) { scheme.bindings[actionIndex] = null; } else { scheme.bindings[actionIndex] = CreateBinding(bindingType, controlType); } } } // Self binding. if (((action.selfBinding == null) != (bindingType == null || !action.combined)) || (action.selfBinding != null && action.selfBinding.GetType() != bindingType)) { if (bindingType == null || !action.combined) { action.selfBinding = null; } else { action.selfBinding = CreateBinding(bindingType, controlType); } } } }
public abstract string GetSourceName(ControlScheme controlScheme, bool forceStandardized);
public static void ControlField <C, T>(Rect position, InputBinding <C, T> binding, GUIContent label, IControlDomainSource domainSource, Action <InputBinding <C, T> > action, SerializedProperty prop = null) where C : InputControl <T> { if (prop != null) { label = EditorGUI.BeginProperty(position, label, prop); } position.height = EditorGUIUtility.singleLineHeight; Rect buttonPosition = EditorGUI.PrefixLabel(position, label); Rect detectPosition = buttonPosition; ControlScheme scheme = domainSource as ControlScheme; bool detectionSupport = (scheme != null); if (detectionSupport) { detectPosition.xMin = detectPosition.xMax - 20; buttonPosition.xMax -= (20 + 4); } if (EditorGUI.DropdownButton(buttonPosition, new GUIContent(GetName(binding, domainSource) ?? "None"), FocusType.Keyboard)) { GenericMenu menu = GetMenu( binding, domainSource, a => { if (prop != null) { Undo.RecordObjects(prop.serializedObject.targetObjects, "Control"); } action(a); if (prop != null) { // Flushing seems necessaary to have prefab property override status change without lag. Undo.FlushUndoRecordObjects(); prop.serializedObject.SetIsDifferentCacheDirty(); } }); menu.DropDown(buttonPosition); // GenericMenu doesn't modify GUI.changed because it relies on a callback, so let's assume that something was changed, so target object dirtying doesn't go missing GUI.changed = true; } if (detectionSupport) { EditorGUI.BeginDisabledGroup(s_Binding != null); //if (Event.current.type == EventType.repaint) // EditorStyles.miniButton.Draw(detectPosition, "O", false, false, s_Binding == binding, false); if (GUI.Toggle(detectPosition, s_Binding == binding, "O", EditorStyles.miniButton) && s_Binding == null) { EditorWindow window = EditorWindow.focusedWindow; window.ShowNotification(new GUIContent("Waiting for input.")); s_BindingListener = (InputControl control) => { if (!(control is C)) { window.ShowNotification(new GUIContent("Incompatible control type.")); window.Repaint(); return(false); } DeviceSlot match = null; Type controlProviderType = control.provider.GetType(); for (int slotIndex = 0; slotIndex < scheme.deviceSlots.Count; slotIndex++) { Type deviceType = scheme.deviceSlots[slotIndex].type.value; if (deviceType == null) { continue; } if (deviceType.IsAssignableFrom(controlProviderType)) { match = scheme.deviceSlots[slotIndex]; break; } } if (match == null) { window.ShowNotification(new GUIContent("Incompatible device type.")); window.Repaint(); return(false); } var newReference = new ControlReferenceBinding <C, T>(); newReference.deviceKey = match.key; newReference.controlHash = control.provider.GetHashForControlIndex(control.index); action(newReference); StopListening(window); return(true); }; InputSystem.ListenForBinding(s_BindingListener); s_Binding = binding; float time = Time.realtimeSinceStartup; s_UpdateCallback = () => { if (Time.realtimeSinceStartup > time + 3) { StopListening(window); } }; EditorApplication.update += s_UpdateCallback; } EditorGUI.EndDisabledGroup(); } if (binding != null && !(binding is ControlReferenceBinding <C, T>)) { EditorGUI.indentLevel++; position.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; binding.OnGUI(position, domainSource); EditorGUI.indentLevel--; } if (prop != null) { EditorGUI.EndProperty(); } }