518 lines
25 KiB
C#
518 lines
25 KiB
C#
#if UNITY_EDITOR
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using UnityEditor;
|
|
|
|
namespace UnityEngine.InputSystem.Editor
|
|
{
|
|
// TODO Make buffers an optional argument and only allocate if not already passed, reuse a common buffer
|
|
|
|
internal static class CopyPasteHelper
|
|
{
|
|
private const string k_CopyPasteMarker = "INPUTASSET ";
|
|
private const string k_StartOfText = "\u0002";
|
|
private const string k_EndOfTransmission = "\u0004";
|
|
private const string k_BindingData = "bindingData";
|
|
private const string k_EndOfBinding = "+++";
|
|
private static readonly Dictionary<Type, string> k_TypeMarker = new Dictionary<Type, string>
|
|
{
|
|
{typeof(InputActionMap), "InputActionMap"},
|
|
{typeof(InputAction), "InputAction"},
|
|
{typeof(InputBinding), "InputBinding"},
|
|
};
|
|
|
|
private static SerializedProperty s_lastAddedElement;
|
|
private static InputActionsEditorState s_State;
|
|
private static bool s_lastClipboardActionWasCut = false;
|
|
|
|
private static bool IsComposite(SerializedProperty property) => property.FindPropertyRelative("m_Flags").intValue == (int)InputBinding.Flags.Composite;
|
|
private static bool IsPartOfComposite(SerializedProperty property) => property.FindPropertyRelative("m_Flags").intValue == (int)InputBinding.Flags.PartOfComposite;
|
|
private static string PropertyName(SerializedProperty property) => property.FindPropertyRelative("m_Name").stringValue;
|
|
|
|
#region Cut
|
|
|
|
public static void CutActionMap(InputActionsEditorState state)
|
|
{
|
|
CopyActionMap(state);
|
|
s_lastClipboardActionWasCut = true;
|
|
}
|
|
|
|
public static void Cut(InputActionsEditorState state)
|
|
{
|
|
Copy(state);
|
|
s_lastClipboardActionWasCut = true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Copy
|
|
|
|
public static void CopyActionMap(InputActionsEditorState state)
|
|
{
|
|
var actionMap = Selectors.GetSelectedActionMap(state)?.wrappedProperty;
|
|
var selectedObject = Selectors.GetSelectedActionMap(state)?.wrappedProperty;
|
|
CopySelectedTreeViewItemsToClipboard(new List<SerializedProperty> {selectedObject}, typeof(InputActionMap), actionMap);
|
|
}
|
|
|
|
public static void Copy(InputActionsEditorState state)
|
|
{
|
|
var actionMap = Selectors.GetSelectedActionMap(state)?.wrappedProperty;
|
|
var selectedObject = Selectors.GetSelectedAction(state)?.wrappedProperty;
|
|
var type = typeof(InputAction);
|
|
if (state.selectionType == SelectionType.Binding)
|
|
{
|
|
selectedObject = Selectors.GetSelectedBinding(state)?.wrappedProperty;
|
|
type = typeof(InputBinding);
|
|
}
|
|
CopySelectedTreeViewItemsToClipboard(new List<SerializedProperty> {selectedObject}, type, actionMap);
|
|
}
|
|
|
|
private static void CopySelectedTreeViewItemsToClipboard(List<SerializedProperty> items, Type type, SerializedProperty actionMap = null)
|
|
{
|
|
var copyBuffer = new StringBuilder();
|
|
CopyItems(items, copyBuffer, type, actionMap);
|
|
EditorHelpers.SetSystemCopyBufferContents(copyBuffer.ToString());
|
|
s_lastClipboardActionWasCut = false;
|
|
}
|
|
|
|
internal static void CopyItems(List<SerializedProperty> items, StringBuilder buffer, Type type, SerializedProperty actionMap)
|
|
{
|
|
buffer.Append(k_CopyPasteMarker);
|
|
buffer.Append(k_TypeMarker[type]);
|
|
foreach (var item in items)
|
|
{
|
|
CopyItemData(item, buffer, type, actionMap);
|
|
buffer.Append(k_EndOfTransmission);
|
|
}
|
|
}
|
|
|
|
private static void CopyItemData(SerializedProperty item, StringBuilder buffer, Type type, SerializedProperty actionMap)
|
|
{
|
|
if (item == null)
|
|
return;
|
|
|
|
buffer.Append(k_StartOfText);
|
|
buffer.Append(item.CopyToJson(true));
|
|
if (type == typeof(InputAction))
|
|
AppendBindingDataForAction(buffer, actionMap, item);
|
|
if (type == typeof(InputBinding) && IsComposite(item))
|
|
AppendBindingDataForComposite(buffer, actionMap, item);
|
|
}
|
|
|
|
private static void AppendBindingDataForAction(StringBuilder buffer, SerializedProperty actionMap, SerializedProperty item)
|
|
{
|
|
buffer.Append(k_BindingData);
|
|
foreach (var binding in GetBindingsForActionInMap(actionMap, item))
|
|
{
|
|
buffer.Append(binding.CopyToJson(true));
|
|
buffer.Append(k_EndOfBinding);
|
|
}
|
|
}
|
|
|
|
private static void AppendBindingDataForComposite(StringBuilder buffer, SerializedProperty actionMap, SerializedProperty item)
|
|
{
|
|
var bindingsArray = actionMap.FindPropertyRelative(nameof(InputActionMap.m_Bindings));
|
|
buffer.Append(k_BindingData);
|
|
foreach (var binding in GetBindingsForComposite(bindingsArray, item.GetIndexOfArrayElement()))
|
|
{
|
|
buffer.Append(binding.CopyToJson(true));
|
|
buffer.Append(k_EndOfBinding);
|
|
}
|
|
}
|
|
|
|
private static IEnumerable<SerializedProperty> GetBindingsForActionInMap(SerializedProperty actionMap, SerializedProperty action)
|
|
{
|
|
var actionName = PropertyName(action);
|
|
var bindingsArray = actionMap.FindPropertyRelative(nameof(InputActionMap.m_Bindings));
|
|
var bindings = bindingsArray.Where(binding => binding.FindPropertyRelative("m_Action").stringValue.Equals(actionName));
|
|
return bindings;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PasteChecks
|
|
public static bool HasPastableClipboardData(Type selectedType)
|
|
{
|
|
var clipboard = EditorHelpers.GetSystemCopyBufferContents();
|
|
if (clipboard.Length < k_CopyPasteMarker.Length)
|
|
return false;
|
|
var isInputAssetData = clipboard.StartsWith(k_CopyPasteMarker);
|
|
return isInputAssetData && IsMatchingType(selectedType, GetCopiedClipboardType());
|
|
}
|
|
|
|
private static bool IsMatchingType(Type selectedType, Type copiedType)
|
|
{
|
|
if (selectedType == typeof(InputActionMap))
|
|
return copiedType == typeof(InputActionMap) || copiedType == typeof(InputAction);
|
|
if (selectedType == typeof(InputAction))
|
|
return copiedType == typeof(InputAction) || copiedType == typeof(InputBinding);
|
|
//bindings and composites
|
|
return copiedType == typeof(InputBinding);
|
|
}
|
|
|
|
public static Type GetCopiedType(string buffer)
|
|
{
|
|
if (!buffer.StartsWith(k_CopyPasteMarker))
|
|
return null;
|
|
foreach (var typePair in k_TypeMarker)
|
|
{
|
|
if (buffer.Substring(k_CopyPasteMarker.Length).StartsWith(typePair.Value))
|
|
return typePair.Key;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static Type GetCopiedClipboardType()
|
|
{
|
|
return GetCopiedType(EditorHelpers.GetSystemCopyBufferContents());
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Paste
|
|
|
|
public static SerializedProperty PasteActionMapsFromClipboard(InputActionsEditorState state)
|
|
{
|
|
s_lastAddedElement = null;
|
|
var typeOfCopiedData = GetCopiedClipboardType();
|
|
if (typeOfCopiedData != typeof(InputActionMap)) return null;
|
|
s_State = state;
|
|
var actionMapArray = state.serializedObject.FindProperty(nameof(InputActionAsset.m_ActionMaps));
|
|
PasteData(EditorHelpers.GetSystemCopyBufferContents(), new[] {state.selectedActionMapIndex}, actionMapArray);
|
|
|
|
// Don't want to be able to paste repeatedly after a cut - ISX-1821
|
|
if (s_lastAddedElement != null && s_lastClipboardActionWasCut)
|
|
EditorHelpers.SetSystemCopyBufferContents(string.Empty);
|
|
|
|
return s_lastAddedElement;
|
|
}
|
|
|
|
public static SerializedProperty PasteActionsOrBindingsFromClipboard(InputActionsEditorState state, bool addLast = false, int mapIndex = -1)
|
|
{
|
|
s_lastAddedElement = null;
|
|
s_State = state;
|
|
var typeOfCopiedData = GetCopiedClipboardType();
|
|
if (typeOfCopiedData == typeof(InputAction))
|
|
PasteActionsFromClipboard(state, addLast, mapIndex);
|
|
if (typeOfCopiedData == typeof(InputBinding))
|
|
PasteBindingsFromClipboard(state);
|
|
|
|
// Don't want to be able to paste repeatedly after a cut - ISX-1821
|
|
if (s_lastAddedElement != null && s_lastClipboardActionWasCut)
|
|
EditorHelpers.SetSystemCopyBufferContents(string.Empty);
|
|
|
|
return s_lastAddedElement;
|
|
}
|
|
|
|
private static void PasteActionsFromClipboard(InputActionsEditorState state, bool addLast, int mapIndex)
|
|
{
|
|
var actionMap = mapIndex >= 0 ? Selectors.GetActionMapAtIndex(state, mapIndex)?.wrappedProperty
|
|
: Selectors.GetSelectedActionMap(state)?.wrappedProperty;
|
|
var actionArray = actionMap?.FindPropertyRelative(nameof(InputActionMap.m_Actions));
|
|
if (actionArray == null) return;
|
|
var index = state.selectedActionIndex;
|
|
if (addLast)
|
|
index = actionArray.arraySize - 1;
|
|
PasteData(EditorHelpers.GetSystemCopyBufferContents(), new[] {index}, actionArray);
|
|
}
|
|
|
|
private static void PasteBindingsFromClipboard(InputActionsEditorState state)
|
|
{
|
|
var actionMap = Selectors.GetSelectedActionMap(state)?.wrappedProperty;
|
|
var bindingsArray = actionMap?.FindPropertyRelative(nameof(InputActionMap.m_Bindings));
|
|
if (bindingsArray == null) return;
|
|
int newBindingIndex;
|
|
if (state.selectionType == SelectionType.Action)
|
|
newBindingIndex = Selectors.GetLastBindingIndexForSelectedAction(state);
|
|
else
|
|
newBindingIndex = state.selectedBindingIndex;
|
|
|
|
PasteData(EditorHelpers.GetSystemCopyBufferContents(), new[] { newBindingIndex }, bindingsArray);
|
|
}
|
|
|
|
private static void PasteData(string copyBufferString, int[] indicesToInsert, SerializedProperty arrayToInsertInto)
|
|
{
|
|
if (!copyBufferString.StartsWith(k_CopyPasteMarker))
|
|
return;
|
|
PasteItems(copyBufferString, indicesToInsert, arrayToInsertInto);
|
|
}
|
|
|
|
internal static void PasteItems(string copyBufferString, int[] indicesToInsert, SerializedProperty arrayToInsertInto)
|
|
{
|
|
// Split buffer into transmissions and then into transmission blocks
|
|
var copiedType = GetCopiedType(copyBufferString);
|
|
int indexOffset = 0;
|
|
// If the array is empty, make sure we insert at index 0
|
|
if (arrayToInsertInto.arraySize == 0)
|
|
indexOffset = -1;
|
|
foreach (var transmission in copyBufferString.Substring(k_CopyPasteMarker.Length + k_TypeMarker[copiedType].Length)
|
|
.Split(new[] {k_EndOfTransmission}, StringSplitOptions.RemoveEmptyEntries))
|
|
{
|
|
indexOffset++;
|
|
foreach (var index in indicesToInsert)
|
|
PasteBlocks(transmission, index + indexOffset, arrayToInsertInto, copiedType);
|
|
}
|
|
}
|
|
|
|
private static void PasteBlocks(string transmission, int indexToInsert, SerializedProperty arrayToInsertInto, Type copiedType)
|
|
{
|
|
var block = transmission.Substring(transmission.IndexOf(k_StartOfText, StringComparison.Ordinal) + 1);
|
|
if (copiedType == typeof(InputActionMap))
|
|
PasteElement(arrayToInsertInto, block, indexToInsert, out _);
|
|
else if (copiedType == typeof(InputAction))
|
|
PasteAction(arrayToInsertInto, block, indexToInsert);
|
|
else
|
|
{
|
|
var actionName = Selectors.GetSelectedBinding(s_State)?.wrappedProperty.FindPropertyRelative("m_Action")
|
|
.stringValue;
|
|
|
|
if (s_State.selectionType == SelectionType.Action)
|
|
{
|
|
SerializedProperty property = Selectors.GetSelectedAction(s_State)?.wrappedProperty;
|
|
if (property == null)
|
|
return;
|
|
actionName = PropertyName(property);
|
|
}
|
|
if (actionName == null)
|
|
return;
|
|
|
|
PasteBindingOrComposite(arrayToInsertInto, block, indexToInsert, actionName);
|
|
}
|
|
}
|
|
|
|
private static SerializedProperty PasteElement(SerializedProperty arrayProperty, string json, int index, out string oldId, string name = "newElement", bool changeName = true, bool assignUniqueIDs = true)
|
|
{
|
|
var duplicatedProperty = AddElement(arrayProperty, name, index);
|
|
duplicatedProperty.RestoreFromJson(json);
|
|
oldId = duplicatedProperty.FindPropertyRelative("m_Id").stringValue;
|
|
if (changeName)
|
|
InputActionSerializationHelpers.EnsureUniqueName(duplicatedProperty);
|
|
if (assignUniqueIDs)
|
|
InputActionSerializationHelpers.AssignUniqueIDs(duplicatedProperty);
|
|
s_lastAddedElement = duplicatedProperty;
|
|
return duplicatedProperty;
|
|
}
|
|
|
|
private static void PasteAction(SerializedProperty arrayProperty, string jsonToInsert, int indexToInsert)
|
|
{
|
|
var json = jsonToInsert.Split(k_BindingData, StringSplitOptions.RemoveEmptyEntries);
|
|
var bindingJsons = new string[] {};
|
|
if (json.Length > 1)
|
|
bindingJsons = json[1].Split(k_EndOfBinding, StringSplitOptions.RemoveEmptyEntries);
|
|
var property = PasteElement(arrayProperty, json[0], indexToInsert, out _, "");
|
|
var newName = PropertyName(property);
|
|
var newId = property.FindPropertyRelative("m_Id").stringValue;
|
|
var actionMapTo = Selectors.GetActionMapForAction(s_State, newId);
|
|
var bindingArrayToInsertTo = actionMapTo.FindPropertyRelative(nameof(InputActionMap.m_Bindings));
|
|
var index = Mathf.Clamp(Selectors.GetBindingIndexBeforeAction(arrayProperty, indexToInsert, bindingArrayToInsertTo), 0, bindingArrayToInsertTo.arraySize);
|
|
foreach (var bindingJson in bindingJsons)
|
|
{
|
|
var newIndex = PasteBindingOrComposite(bindingArrayToInsertTo, bindingJson, index, newName, false);
|
|
index = newIndex;
|
|
}
|
|
s_lastAddedElement = property;
|
|
}
|
|
|
|
private static int PasteBindingOrComposite(SerializedProperty arrayProperty, string json, int index, string actionName, bool createCompositeParts = true)
|
|
{
|
|
var pastePartOfComposite = IsPartOfComposite(json);
|
|
bool currentPartOfComposite = false;
|
|
bool currentIsComposite = false;
|
|
|
|
if (arrayProperty.arraySize == 0)
|
|
index = 0;
|
|
|
|
if (index > 0)
|
|
{
|
|
var currentProperty = arrayProperty.GetArrayElementAtIndex(index - 1);
|
|
currentPartOfComposite = IsPartOfComposite(currentProperty);
|
|
currentIsComposite = IsComposite(currentProperty) || currentPartOfComposite;
|
|
if (pastePartOfComposite && !currentIsComposite) //prevent pasting part of composite into non-composite
|
|
return index;
|
|
}
|
|
|
|
// Update the target index for special cases when pasting a Binding
|
|
if (s_State.selectionType != SelectionType.Action && createCompositeParts)
|
|
{
|
|
// - Pasting into a Composite with CompositePart not the target, i.e. Composite "root" selected, paste at the end of the composite
|
|
// - Pasting a non-CompositePart, i.e. regular Binding, needs to skip all the CompositeParts (if any)
|
|
if ((pastePartOfComposite && !currentPartOfComposite) || !pastePartOfComposite)
|
|
index = Selectors.GetSelectedBindingIndexAfterCompositeBindings(s_State) + 1;
|
|
}
|
|
|
|
if (json.Contains(k_BindingData)) //copied data is composite with bindings - only true for directly copied composites, not for composites from copied actions
|
|
return PasteCompositeFromJson(arrayProperty, json, index, actionName);
|
|
var property = PasteElement(arrayProperty, json, index, out var oldId, "", false);
|
|
if (IsComposite(property))
|
|
return PasteComposite(arrayProperty, property, PropertyName(property), actionName, index, oldId, createCompositeParts); //Paste composites copied with actions
|
|
property.FindPropertyRelative("m_Action").stringValue = actionName;
|
|
return index + 1;
|
|
}
|
|
|
|
private static int PasteComposite(SerializedProperty bindingsArray, SerializedProperty duplicatedComposite, string name, string actionName, int index, string oldId, bool createCompositeParts)
|
|
{
|
|
duplicatedComposite.FindPropertyRelative("m_Name").stringValue = name;
|
|
duplicatedComposite.FindPropertyRelative("m_Action").stringValue = actionName;
|
|
if (createCompositeParts)
|
|
{
|
|
var composite = Selectors.GetBindingForId(s_State, oldId, out var bindingsFrom);
|
|
var bindings = GetBindingsForComposite(bindingsFrom, composite.GetIndexOfArrayElement());
|
|
PastePartsOfComposite(bindingsArray, bindings, ++index, actionName);
|
|
}
|
|
return index + 1;
|
|
}
|
|
|
|
private static int PastePartsOfComposite(SerializedProperty bindingsToInsertTo, List<SerializedProperty> bindingsOfComposite, int index, string actionName)
|
|
{
|
|
foreach (var binding in bindingsOfComposite)
|
|
{
|
|
var newBinding = DuplicateElement(bindingsToInsertTo, binding, PropertyName(binding), index++, false);
|
|
newBinding.FindPropertyRelative("m_Action").stringValue = actionName;
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
private static int PasteCompositeFromJson(SerializedProperty arrayProperty, string json, int index, string actionName)
|
|
{
|
|
var jsons = json.Split(k_BindingData, StringSplitOptions.RemoveEmptyEntries);
|
|
var property = PasteElement(arrayProperty, jsons[0], index, out _, "", false);
|
|
var bindingJsons = jsons[1].Split(k_EndOfBinding, StringSplitOptions.RemoveEmptyEntries);
|
|
property.FindPropertyRelative("m_Action").stringValue = actionName;
|
|
foreach (var bindingJson in bindingJsons)
|
|
PasteBindingOrComposite(arrayProperty, bindingJson, ++index, actionName, false);
|
|
return index + 1;
|
|
}
|
|
|
|
private static bool IsPartOfComposite(string json)
|
|
{
|
|
if (!json.Contains("m_Flags") || json.Contains(k_BindingData))
|
|
return false;
|
|
var ob = JsonUtility.FromJson<InputBinding>(json);
|
|
return ob.m_Flags == InputBinding.Flags.PartOfComposite;
|
|
}
|
|
|
|
private static SerializedProperty AddElement(SerializedProperty arrayProperty, string name, int index = -1)
|
|
{
|
|
var uniqueName = InputActionSerializationHelpers.FindUniqueName(arrayProperty, name);
|
|
if (index < 0)
|
|
index = arrayProperty.arraySize;
|
|
|
|
arrayProperty.InsertArrayElementAtIndex(index);
|
|
var elementProperty = arrayProperty.GetArrayElementAtIndex(index);
|
|
elementProperty.ResetValuesToDefault();
|
|
|
|
elementProperty.FindPropertyRelative("m_Name").stringValue = uniqueName;
|
|
elementProperty.FindPropertyRelative("m_Id").stringValue = Guid.NewGuid().ToString();
|
|
|
|
return elementProperty;
|
|
}
|
|
|
|
public static int DeleteCutElements(InputActionsEditorState state)
|
|
{
|
|
if (!state.hasCutElements)
|
|
return -1;
|
|
var cutElements = state.GetCutElements();
|
|
var index = state.selectedActionMapIndex;
|
|
if (cutElements[0].type == typeof(InputAction))
|
|
index = state.selectedActionIndex;
|
|
else if (cutElements[0].type == typeof(InputBinding))
|
|
index = state.selectionType == SelectionType.Binding ? state.selectedBindingIndex : state.selectedActionIndex;
|
|
|
|
foreach (var cutElement in cutElements)
|
|
{
|
|
var cutIndex = cutElement.GetIndexOfProperty(state);
|
|
var actionMapIndex = cutElement.actionMapIndex(state);
|
|
var actionMap = Selectors.GetActionMapAtIndex(state, actionMapIndex)?.wrappedProperty;
|
|
var isInsertBindingIntoAction = cutElement.type == typeof(InputBinding) && state.selectionType == SelectionType.Action;
|
|
if (cutElement.type == typeof(InputBinding) || cutElement.type == typeof(InputAction))
|
|
{
|
|
if (cutElement.type == typeof(InputAction))
|
|
{
|
|
var action = Selectors.GetActionForIndex(actionMap, cutIndex);
|
|
var id = InputActionSerializationHelpers.GetId(action);
|
|
InputActionSerializationHelpers.DeleteActionAndBindings(actionMap, id);
|
|
}
|
|
else
|
|
{
|
|
var binding = Selectors.GetCompositeOrBindingInMap(actionMap, cutIndex).wrappedProperty;
|
|
if (binding.FindPropertyRelative("m_Flags").intValue == (int)InputBinding.Flags.Composite && !isInsertBindingIntoAction)
|
|
index -= InputActionSerializationHelpers.GetCompositePartCount(Selectors.GetSelectedActionMap(state)?.wrappedProperty.FindPropertyRelative(nameof(InputActionMap.m_Bindings)), cutIndex);
|
|
InputActionSerializationHelpers.DeleteBinding(binding, actionMap);
|
|
}
|
|
if (cutIndex <= index && actionMapIndex == state.selectedActionMapIndex && !isInsertBindingIntoAction)
|
|
index--;
|
|
}
|
|
else if (cutElement.type == typeof(InputActionMap))
|
|
{
|
|
InputActionSerializationHelpers.DeleteActionMap(state.serializedObject, InputActionSerializationHelpers.GetId(actionMap));
|
|
if (cutIndex <= index)
|
|
index--;
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Duplicate
|
|
public static void DuplicateAction(SerializedProperty arrayProperty, SerializedProperty toDuplicate, SerializedProperty actionMap, InputActionsEditorState state)
|
|
{
|
|
s_State = state;
|
|
var buffer = new StringBuilder();
|
|
buffer.Append(toDuplicate.CopyToJson(true));
|
|
AppendBindingDataForAction(buffer, actionMap, toDuplicate);
|
|
PasteAction(arrayProperty, buffer.ToString(), toDuplicate.GetIndexOfArrayElement() + 1);
|
|
}
|
|
|
|
public static int DuplicateBinding(SerializedProperty arrayProperty, SerializedProperty toDuplicate, string newActionName, int index)
|
|
{
|
|
if (IsComposite(toDuplicate))
|
|
return DuplicateComposite(arrayProperty, toDuplicate, PropertyName(toDuplicate), newActionName, index, out _).GetIndexOfArrayElement();
|
|
var binding = DuplicateElement(arrayProperty, toDuplicate, newActionName, index, false);
|
|
binding.FindPropertyRelative("m_Action").stringValue = newActionName;
|
|
return index;
|
|
}
|
|
|
|
private static SerializedProperty DuplicateComposite(SerializedProperty bindingsArray, SerializedProperty compositeToDuplicate, string name, string actionName, int index, out int newIndex, bool increaseIndex = true)
|
|
{
|
|
if (increaseIndex)
|
|
index += InputActionSerializationHelpers.GetCompositePartCount(bindingsArray, compositeToDuplicate.GetIndexOfArrayElement());
|
|
var newComposite = DuplicateElement(bindingsArray, compositeToDuplicate, name, index++, false);
|
|
newComposite.FindPropertyRelative("m_Action").stringValue = actionName;
|
|
var bindings = GetBindingsForComposite(bindingsArray, compositeToDuplicate.GetIndexOfArrayElement());
|
|
newIndex = PastePartsOfComposite(bindingsArray, bindings, index, actionName);
|
|
return newComposite;
|
|
}
|
|
|
|
public static SerializedProperty DuplicateElement(SerializedProperty arrayProperty, SerializedProperty toDuplicate, string name, int index, bool changeName = true)
|
|
{
|
|
var json = toDuplicate.CopyToJson(true);
|
|
return PasteElement(arrayProperty, json, index, out _, name, changeName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
internal static List<SerializedProperty> GetBindingsForComposite(SerializedProperty bindingsArray, int indexOfComposite)
|
|
{
|
|
var compositeBindings = new List<SerializedProperty>();
|
|
var compositeStartIndex = InputActionSerializationHelpers.GetCompositeStartIndex(bindingsArray, indexOfComposite);
|
|
if (compositeStartIndex == -1)
|
|
return compositeBindings;
|
|
|
|
for (var i = compositeStartIndex + 1; i < bindingsArray.arraySize; ++i)
|
|
{
|
|
var bindingProperty = bindingsArray.GetArrayElementAtIndex(i);
|
|
var bindingFlags = (InputBinding.Flags)bindingProperty.FindPropertyRelative("m_Flags").intValue;
|
|
if ((bindingFlags & InputBinding.Flags.PartOfComposite) == 0)
|
|
break;
|
|
compositeBindings.Add(bindingProperty);
|
|
}
|
|
return compositeBindings;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|