This commit is contained in:
2021-06-13 10:28:03 +02:00
parent eb70603c85
commit df2d24cbd3
7487 changed files with 943244 additions and 0 deletions

View File

@@ -0,0 +1,676 @@
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.U2D.Animation;
namespace UnityEditor.U2D.Animation
{
internal class SpriteLibraryDataInspector
{
class Style
{
public GUIContent duplicateWarningText = EditorGUIUtility.TrTextContent("Duplicate name found or name hash clashes. Please use a different name");
public GUIContent duplicateWarning;
public int lineSpacing = 3;
public int spriteGridSize = 64;
public float gridPadding = EditorGUIUtility.standardVerticalSpacing * 2;
public int gridHeaderSize = 20;
public int gridFooterSize = 20;
public float gridHeight;
public Vector2 gridSize;
public GUIStyle footerBackground;
public GUIStyle boxBackground;
public GUIStyle preButton;
public GUIStyle headerBackground;
public GUIStyle gridList;
public GUIContent iconToolbarPlus = EditorGUIUtility.TrIconContent("Toolbar Plus", "Add to list");
public GUIContent iconToolbarMinus = EditorGUIUtility.TrIconContent("Toolbar Minus", "Remove selection or last element from list");
public GUIContent overrideIcon = EditorGUIUtility.TrIconContent("PrefabOverlayAdded Icon");
public string newCategoryText = L10n.Tr("New Category");
public string categoryLabel = L10n.Tr("Category");
public float categoryElementHeight;
public float categoryTextFieldHeight;
public string newEntryText = L10n.Tr("Entry");
public float categoryLabelWidth = 100;
public Style()
{
gridSize = new Vector2(spriteGridSize + gridPadding * 2,
spriteGridSize + lineSpacing + EditorGUIUtility.singleLineHeight + gridPadding * 2);
duplicateWarning = EditorGUIUtility.TrIconContent("console.warnicon.sml", duplicateWarningText.text);
gridHeight = gridSize.y +gridPadding + gridFooterSize;
categoryTextFieldHeight = EditorGUIUtility.singleLineHeight + lineSpacing;
categoryElementHeight = gridHeight + categoryTextFieldHeight + gridHeaderSize;
}
public void InitStyle(Event currentEvent)
{
if (footerBackground == null && currentEvent.type == EventType.Repaint)
{
footerBackground = "RL Footer";
boxBackground = "RL Background";
preButton = "RL FooterButton";
headerBackground = "RL Header";
gridList = "GridList";
}
}
}
class SpriteCategoryGridState
{
public Vector2 scrollPos;
public int selectedIndex;
public static SpriteCategoryGridState Default =>
new SpriteCategoryGridState()
{
scrollPos = Vector2.zero,
selectedIndex = 0
};
}
private Style m_Style;
private SerializedProperty m_Library;
private List<SpriteCategoryGridState> m_GridStates = new List<SpriteCategoryGridState>();
private ReorderableList m_LabelReorderableList;
public SpriteLibraryDataInspector(SerializedObject so,
SerializedProperty library)
{
m_Style = new Style();
m_Library = library;
m_LabelReorderableList = new ReorderableList(so, library, true, false,
true, true);
m_LabelReorderableList.drawElementCallback = DrawElement;
m_LabelReorderableList.elementHeight = m_Style.categoryTextFieldHeight;
m_LabelReorderableList.elementHeightCallback = delegate(int index) { return m_Style.categoryElementHeight; };
m_LabelReorderableList.onAddCallback = OnAddCallback;
m_LabelReorderableList.onCanRemoveCallback = OnCanRemoveCallback;
}
public static void UpdateLibraryWithNewMainLibrary(SpriteLibraryAsset spriteLib, SerializedProperty library)
{
var emptyStringArray = new string[0];
var categories = spriteLib != null ? spriteLib.GetCategoryNames() : emptyStringArray;
// populate new primary
int newCatgoryIndex = 0;
foreach (var newCategory in categories)
{
SerializedProperty existingCategory = null;
if (library.arraySize > 0)
{
var cat = library.GetArrayElementAtIndex(0);
for (int i = 0; i < library.arraySize; ++i)
{
if (cat.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue == newCategory)
{
existingCategory = cat;
if(i != newCatgoryIndex)
library.MoveArrayElement(i, newCatgoryIndex);
break;
}
cat.Next(false);
}
}
if (existingCategory != null)
{
if(!existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue)
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true;
}
else
{
library.InsertArrayElementAtIndex(newCatgoryIndex);
existingCategory = library.GetArrayElementAtIndex(newCatgoryIndex);
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true;
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newCategory;
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue = 0;
existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries).arraySize = 0;
}
newCatgoryIndex++;
var newEntries = spriteLib.GetCategoryLabelNames(newCategory);
var entries = existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
int newEntryIndex = 0;
foreach (var newEntry in newEntries)
{
SerializedProperty cacheEntry = null;
if (entries.arraySize > 0)
{
var ent = entries.GetArrayElementAtIndex(0);
for (int j = 0; j < entries.arraySize; ++j)
{
if (ent.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue == newEntry)
{
cacheEntry = ent;
if(j != newEntryIndex)
entries.MoveArrayElement(j, newEntryIndex);
break;
}
ent.Next(false);
}
}
var mainSprite = spriteLib.GetSprite(newCategory, newEntry);
if (cacheEntry == null)
{
entries.InsertArrayElementAtIndex(newEntryIndex);
cacheEntry = entries.GetArrayElementAtIndex(newEntryIndex);
cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newEntry;
cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride)
.objectReferenceValue = mainSprite;
}
++newEntryIndex;
if(!cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue)
cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true;
if(cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue != mainSprite)
cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue = mainSprite;
}
}
// Remove any library or entry that is not in primary and not overridden
for (int i = 0; i < library.arraySize; ++i)
{
var categoryProperty = library.GetArrayElementAtIndex(i);
var categoryEntriesProperty = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
var categoryFromMainProperty = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.fromMain);
var categoryName = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
var categoryInPrimary = categories.Contains(categoryName);
var entriesInPrimary = categoryInPrimary ? spriteLib.GetCategoryLabelNames(categoryName) : emptyStringArray;
var categoryOverride = 0;
for (int j = 0; j < categoryEntriesProperty.arraySize; ++j)
{
var entry = categoryEntriesProperty.GetArrayElementAtIndex(j);
var entryName = entry.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
var entryInPrimary = entriesInPrimary.Contains(entryName);
var entryFromMainProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain);
var overrideSpriteProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride);
var spriteProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.sprite);
if (!entryInPrimary)
{
// Entry no longer in new primary.
// Check for override and set it to us
if (entryFromMainProperty.boolValue)
{
if (overrideSpriteProperty.objectReferenceValue == spriteProperty.objectReferenceValue)
{
categoryEntriesProperty.DeleteArrayElementAtIndex(j);
--j;
continue;
}
}
if(entryFromMainProperty.boolValue)
entryFromMainProperty.boolValue = false;
if(spriteProperty.objectReferenceValue != overrideSpriteProperty.objectReferenceValue)
spriteProperty.objectReferenceValue = overrideSpriteProperty.objectReferenceValue;
++categoryOverride;
}
else
{
// Check if sprite has been override
if(spriteProperty.objectReferenceValue != overrideSpriteProperty.objectReferenceValue)
++categoryOverride;
}
}
if (!categoryInPrimary && categoryEntriesProperty.arraySize == 0 && categoryFromMainProperty.boolValue)
{
library.DeleteArrayElementAtIndex(i);
--i;
continue;
}
// since there is override, and we removed the main. This category now
// belows to the library
if (!categoryInPrimary)
{
if(categoryFromMainProperty.boolValue)
categoryFromMainProperty.boolValue = false;
}
else
{
if(categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue != categoryOverride)
categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue = categoryOverride;
}
}
}
public void OnGUI()
{
m_Style.InitStyle(Event.current);
m_LabelReorderableList.DoLayoutList();
HandleCategoryCreateSpriteDragAndDrop();
}
void HandleCategoryCreateSpriteDragAndDrop()
{
bool dragAccepted = false;
switch (Event.current.type)
{
case EventType.DragPerform:
foreach (var obj in DragAndDrop.objectReferences)
{
if (obj is Sprite || obj is Texture2D)
{
dragAccepted = true;
}
}
if (dragAccepted)
{
DragAndDrop.AcceptDrag();
foreach (var obj in DragAndDrop.objectReferences)
{
if (obj is Sprite)
{
var category = AddCategory(obj.name, false);
AddSpriteToCategory(category, (Sprite)obj);
}
else if (obj is Texture2D)
{
var sprites = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(obj))
.Where(x => x is Sprite);
foreach (var s in sprites)
{
var category = AddCategory(s.name, false);
AddSpriteToCategory(category, (Sprite)s);
}
}
}
}
Event.current.Use();
break;
case EventType.DragUpdated:
if (DragAndDrop.objectReferences.Count(x => x is Sprite || x is Texture2D) > 0)
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
else
DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
Event.current.Use();
break;
}
}
SerializedProperty IsCategoryNameInUsed(string name)
{
if (m_Library.arraySize == 0)
return null;
var nameHash = SpriteLibraryAsset.GetStringHash(name);
var sp = m_Library.GetArrayElementAtIndex(0);
for (int i = 0; i < m_Library.arraySize; ++i)
{
var nameProperty = sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
var hash = SpriteLibraryAsset.GetStringHash(nameProperty);
if (nameProperty == name || nameHash == hash)
return sp;
sp.Next(false);
}
return null;
}
void DrawElement(Rect rect, int index, bool selected, bool focused)
{
var categorySerializedProperty = m_Library.GetArrayElementAtIndex(index);
var catRect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
var vaRect = new Rect(rect.x, rect.y + m_Style.categoryTextFieldHeight, rect.width, EditorGUIUtility.singleLineHeight);
var categoryName = categorySerializedProperty.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
var fromMain = categorySerializedProperty.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue;
using (new EditorGUI.DisabledScope(fromMain))
{
EditorGUI.BeginChangeCheck();
var oldLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = m_Style.categoryLabelWidth;
var newCatName = EditorGUI.DelayedTextField(catRect, m_Style.categoryLabel, categoryName);
EditorGUIUtility.labelWidth = oldLabelWidth;
if (EditorGUI.EndChangeCheck())
{
newCatName = newCatName.Trim();
if (categoryName != newCatName)
{
// Check if this nameLabel is already taken
if (IsCategoryNameInUsed(newCatName) == null)
categorySerializedProperty.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newCatName;
else
Debug.LogWarning(m_Style.duplicateWarningText.text);
}
}
}
while(m_GridStates.Count <= index)
m_GridStates.Add(new SpriteCategoryGridState());
DrawCategorySpriteListHeader(vaRect, m_Style.newEntryText);
vaRect.y += vaRect.height;
vaRect.height = m_Style.gridHeight;
DrawCategorySpriteList(vaRect, index, categorySerializedProperty);
HandleSpriteDragAndDropToCategory(vaRect, categorySerializedProperty);
}
void OnAddCallback(ReorderableList list)
{
AddCategory(m_Style.newCategoryText, true);
}
SerializedProperty AddCategory(string categoryName, bool createNew)
{
var intendedCategoryName = categoryName;
int catNameIncrement = 1;
while (true)
{
var catOverride = IsCategoryNameInUsed(categoryName);
if (catOverride != null)
{
if (!createNew)
return catOverride;
categoryName = string.Format("{0} {1}", intendedCategoryName, catNameIncrement++);
}
else
break;
}
var oldSize = m_Library.arraySize;
m_Library.arraySize += 1;
var sp = m_Library.GetArrayElementAtIndex(oldSize);
sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = categoryName;
sp.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = false;
sp.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries).arraySize = 0;
return sp;
}
bool HandleSpriteDragAndDropToCategory(Rect rect, SerializedProperty category)
{
bool dragAccepted = false;
if (rect.Contains(Event.current.mousePosition))
{
switch (Event.current.type)
{
case EventType.DragPerform:
foreach (var obj in DragAndDrop.objectReferences)
{
if (obj is Sprite)
{
AddSpriteToCategory(category, (Sprite)obj);
dragAccepted = true;
}
}
if (dragAccepted)
{
DragAndDrop.AcceptDrag();
}
Event.current.Use();
break;
case EventType.DragUpdated:
if (DragAndDrop.objectReferences.Count(x => x is Sprite) > 0)
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
else
DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
Event.current.Use();
break;
}
}
return dragAccepted;
}
static void GetRowColumnCount(float drawWidth, float size, int contentCount, out int column, out int row, out float columnf)
{
columnf = (drawWidth) / size;
column = (int)Mathf.Floor(columnf);
if (column == 0)
row = 0;
else
row = (int)Mathf.Ceil((contentCount + column-1) / column);
}
public void DrawCategorySpriteList(Rect rect, int index, SerializedProperty category)
{
var spriteListProp = category.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
var footerRect = rect;
var gridState = m_GridStates[index];
gridState.selectedIndex = (gridState.selectedIndex > spriteListProp.arraySize) ? 0 : gridState.selectedIndex;
rect.height -= m_Style.gridFooterSize;
if(Event.current.type == EventType.Repaint)
m_Style.boxBackground.Draw(rect, "", false, false, false, false);
rect.x += m_Style.gridPadding;
rect.y += m_Style.gridPadding;
rect.width -= m_Style.gridPadding * 2;
rect.height -= m_Style.gridPadding * 2;
float columnF;
int columnCount, rowCount;
GetRowColumnCount(rect.width, m_Style.gridSize.x, spriteListProp.arraySize, out columnCount, out rowCount, out columnF);
bool canRemoveSelectedEntry = true;
bool selectedEntryIsOverwrite = false;
var overrideCountProperty = category.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount);
if (spriteListProp.arraySize <= 0 && overrideCountProperty.intValue != 0)
overrideCountProperty.intValue = 0;
if (columnCount > 0 && rowCount > 0)
{
var spriteOverwrite = 0;
var scrollViewRect = new Rect(rect.x, rect.y, columnCount * m_Style.gridSize.x,
rowCount * m_Style.gridSize.y);
if (rowCount >= 2)
gridState.scrollPos = GUI.BeginScrollView(new Rect(rect.x, rect.y, rect.width, rect.height),gridState.scrollPos, scrollViewRect, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar);
var spriteObjectFieldRect = new Rect(rect.x, rect.y, m_Style.spriteGridSize, m_Style.spriteGridSize);
var labelTextfieldRect = new Rect(rect.x, rect.y + m_Style.spriteGridSize + m_Style.lineSpacing, m_Style.spriteGridSize, EditorGUIUtility.singleLineHeight);
var backgroundSelectedRect = new Rect(rect.x, rect.y, m_Style.gridSize.x, m_Style.gridSize.y);
for (int i = 0, row = 0, column = 0; i < spriteListProp.arraySize; ++i, ++column)
{
var element = spriteListProp.GetArrayElementAtIndex(i);
var spriteProperty = element.FindPropertyRelative(SpriteLibraryPropertyString.sprite);
var spriteOverrideProperty = element.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride);
var spriteOverride = spriteProperty.objectReferenceValue != spriteOverrideProperty.objectReferenceValue;
var entryFromMain = element.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue;
if (column >= columnCount)
{
column = 0;
++row;
}
backgroundSelectedRect.x = column * m_Style.gridSize.x + rect.x;
backgroundSelectedRect.y = row * m_Style.gridSize.y + rect.y;
spriteObjectFieldRect.x = column * m_Style.gridSize.x + rect.x + m_Style.gridPadding;
spriteObjectFieldRect.y = row * m_Style.gridSize.y + rect.y + m_Style.gridPadding;
labelTextfieldRect.x = column * m_Style.gridSize.x +rect.x + m_Style.gridPadding;
labelTextfieldRect.y = row * m_Style.gridSize.y + m_Style.spriteGridSize +rect.y + m_Style.gridPadding;
if (gridState.selectedIndex == i)
{
canRemoveSelectedEntry = entryFromMain && spriteOverride || !entryFromMain;
selectedEntryIsOverwrite = entryFromMain && spriteOverride;
if(Event.current.type == EventType.Repaint)
m_Style.gridList.Draw(backgroundSelectedRect, true, true, true, false);
}
spriteOverrideProperty.objectReferenceValue = EditorGUI.ObjectField(spriteObjectFieldRect, spriteOverrideProperty.objectReferenceValue, typeof(Sprite), false) as Sprite;
if (Event.current.type == EventType.MouseUp &&
backgroundSelectedRect.Contains(Event.current.mousePosition))
{
gridState.selectedIndex = i;
}
if (!entryFromMain || spriteOverride)
{
var overrideIconRect = spriteObjectFieldRect;
overrideIconRect.x -= 12;
overrideIconRect.y -= 12;
overrideIconRect.width = 20;
overrideIconRect.height = 20;
GUI.Label(overrideIconRect, m_Style.overrideIcon);
++spriteOverwrite;
}
//disable m_Name editing if the entry is from main
using (new EditorGUI.DisabledScope(entryFromMain))
{
EditorGUI.BeginChangeCheck();
var oldName = element.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
if (string.IsNullOrEmpty(oldName) && spriteOverrideProperty.objectReferenceValue != null && entryFromMain)
{
oldName = spriteOverrideProperty.name;
element.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = oldName;
}
var nameRect = labelTextfieldRect;
bool nameDuplicate = IsEntryNameUsed(oldName, spriteListProp, 1);
if (nameDuplicate)
{
nameRect.width -= 20;
}
var newName = EditorGUI.DelayedTextField(
nameRect,
GUIContent.none,
oldName);
if (nameDuplicate)
{
nameRect.x += nameRect.width;
nameRect.width = 20;
GUI.Label(nameRect, m_Style.duplicateWarning);
}
if (EditorGUI.EndChangeCheck() && !string.IsNullOrEmpty(newName))
{
newName = newName.Trim();
element.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newName;
}
}
}
if (overrideCountProperty.intValue != spriteOverwrite)
{
overrideCountProperty.intValue = spriteOverwrite;
GUI.changed = true;
}
if (rowCount >= 2)
GUI.EndScrollView();
}
footerRect = new Rect(footerRect.x, footerRect.y + footerRect.height - m_Style.gridFooterSize, footerRect.width, m_Style.gridFooterSize);
Action<SerializedProperty , SpriteCategoryGridState> removeCallback = DeleteSpriteEntry;
if (selectedEntryIsOverwrite)
removeCallback = DeleteSpriteEntryOverride;
DrawCategorySpriteListFooter(footerRect, category, gridState,canRemoveSelectedEntry, removeCallback);
}
bool IsEntryNameUsed(string name, SerializedProperty spriteList, int duplicateAllow)
{
if (spriteList.arraySize == 0)
return false;
var sp = spriteList.GetArrayElementAtIndex(0);
var nameHash = SpriteLibraryAsset.GetStringHash(name);
int count = 0;
for (int i = 0; i < spriteList.arraySize; ++i, sp.Next(false))
{
var stringValue = sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue;
var hash = SpriteLibraryAsset.GetStringHash(stringValue);
if (stringValue == name || hash == nameHash)
{
++count;
if(count > duplicateAllow)
return true;
}
}
return false;
}
static void DeleteSpriteEntryOverride(SerializedProperty spriteList, SpriteCategoryGridState gridState)
{
var sp = spriteList.GetArrayElementAtIndex(gridState.selectedIndex);
sp.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride).objectReferenceValue = sp.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue;
}
static void DeleteSpriteEntry(SerializedProperty spriteList, SpriteCategoryGridState gridState)
{
spriteList.DeleteArrayElementAtIndex(gridState.selectedIndex);
var count = spriteList.arraySize;
gridState.selectedIndex = (gridState.selectedIndex >= count) ? count - 1 : gridState.selectedIndex;
}
void DrawCategorySpriteListHeader(Rect rect, string text)
{
if (Event.current.type == UnityEngine.EventType.Repaint)
m_Style.headerBackground.Draw(rect, false, false, false, false);
rect.x += 10;
EditorGUI.LabelField(rect, text);
}
void DrawCategorySpriteListFooter(Rect rect, SerializedProperty category, SpriteCategoryGridState gridState, bool canRemove, Action<SerializedProperty, SpriteCategoryGridState> onRemove)
{
float num = rect.xMax - 10f;
float x = num - 8f;
x -= 25f;
x -= 25f;
rect = new Rect(x, rect.y, num - x, rect.height);
Rect rect1 = new Rect(x + 4f, rect.y, 25f, 16f);
Rect position = new Rect(num - 29f, rect.y, 25f, 16f);
if (Event.current.type == UnityEngine.EventType.Repaint)
m_Style.footerBackground.Draw(rect, false, false, false, false);
if (GUI.Button(rect1, m_Style.iconToolbarPlus, m_Style.preButton))
AddSpriteToCategory(category, null);
var spriteList = category.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
using (new EditorGUI.DisabledScope(!canRemove || gridState.selectedIndex < 0 || spriteList.arraySize <= gridState.selectedIndex))
{
if (GUI.Button(position, m_Style.iconToolbarMinus, m_Style.preButton))
onRemove(spriteList, gridState);
}
}
string GetUniqueEntryName(SerializedProperty list, string name)
{
var newName = name;
var count = 0;
while (IsEntryNameUsed(newName, list, 0))
{
newName = string.Format("{0}_{1}", name, count);
++count;
}
return newName;
}
void AddSpriteToCategory(SerializedProperty category, Sprite sprite)
{
var name = sprite == null ? m_Style.newEntryText : sprite.name;
var spriteList = category.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries);
name = GetUniqueEntryName(spriteList, name);
spriteList.arraySize += 1;
var sp = spriteList.GetArrayElementAtIndex(spriteList.arraySize - 1);
sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = name;
sp.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue = sprite;
sp.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride).objectReferenceValue = sprite;
sp.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = false;
}
bool OnCanRemoveCallback(ReorderableList list)
{
bool canDelete = true;
if (list.index >= 0 && list.index < list.count)
{
var item = list.serializedProperty.GetArrayElementAtIndex(list.index);
canDelete = !item.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue;
}
return canDelete;
}
}
}

View File

@@ -0,0 +1,155 @@
using System.Collections.Generic;
using System.IO;
using UnityEditor.AssetImporters;
using UnityEngine;
using UnityEngine.U2D.Animation;
namespace UnityEditor.U2D.Animation
{
/// <summary>
/// A ScriptedImporter that imports .spriteLib extension file to generate
/// SpriteLibraryAsset
/// </summary>
[ScriptedImporter(1, "spriteLib")]
public class SpriteLibrarySourceAssetImporter : ScriptedImporter
{
[SerializeField]
private SpriteLibraryAsset m_PrimaryLibrary;
/// <summary>
/// Implementation of ScriptedImporter.OnImportAsset
/// </summary>
/// <param name="ctx">
/// This argument contains all the contextual information needed to process the import
/// event and is also used by the custom importer to store the resulting Unity Asset.
/// </param>
public override void OnImportAsset(AssetImportContext ctx)
{
var spriteLib = ScriptableObject.CreateInstance<SpriteLibraryAsset>();
spriteLib.name = System.IO.Path.GetFileNameWithoutExtension(assetPath);
var sourceAsset = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(assetPath);
if (sourceAsset?.Length > 0)
{
var sourceLibraryAsset = sourceAsset[0] as SpriteLibrarySourceAsset;
if (sourceLibraryAsset != null)
{
foreach (var cat in sourceLibraryAsset.library)
{
spriteLib.AddCategoryLabel(null, cat.name, null);
foreach (var entry in cat.overrideEntries)
{
spriteLib.AddCategoryLabel(entry.spriteOverride, cat.name, entry.name);
}
}
}
if (!string.IsNullOrEmpty(sourceLibraryAsset.primaryLibraryID))
{
var primaryAssetPath = AssetDatabase.GUIDToAssetPath(sourceLibraryAsset.primaryLibraryID);
if (primaryAssetPath != assetPath)
{
ctx.DependsOnArtifact(AssetDatabase.GUIDToAssetPath(sourceLibraryAsset.primaryLibraryID));
m_PrimaryLibrary = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(primaryAssetPath);
}
}
}
ctx.AddObjectToAsset("SpriteLib", spriteLib, IconUtility.LoadIconResource("Sprite Library", "Icons/Light", "Icons/Dark"));
}
internal static SpriteLibrarySourceAsset LoadSpriteLibrarySourceAsset(string path)
{
var loadedObjects = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(path);
foreach (var obj in loadedObjects)
{
if (obj is SpriteLibrarySourceAsset)
return (SpriteLibrarySourceAsset)obj;
}
return null;
}
internal static void SaveSpriteLibrarySourceAsset(SpriteLibrarySourceAsset obj, string path)
{
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new [] {obj}, path, true);
}
[MenuItem("internal:Assets/Convert to SpriteLibrarySourceAsset", true)]
static bool ConvertToSpriteLibrarySourceAssetValidate()
{
foreach (var obj in Selection.objects)
{
if (obj is SpriteLibraryAsset)
return true;
}
return false;
}
[MenuItem("internal:Assets/Convert to SpriteLibrarySourceAsset")]
static void ConvertToSourceAsset()
{
foreach (var obj in Selection.objects)
{
if (obj is SpriteLibraryAsset)
{
var asset = (SpriteLibraryAsset) obj;
var path = AssetDatabase.GetAssetPath(asset);
var currentAssetPath = Path.GetDirectoryName(path);
var fileName = Path.GetFileNameWithoutExtension(path);
var convertFileName = fileName + ".spriteLib";
convertFileName = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(currentAssetPath, convertFileName));
var convertAsset = ScriptableObject.CreateInstance<SpriteLibrarySourceAsset>();
convertAsset.library = new List<SpriteLibCategoryOverride>(asset.categories.Count);
for (int i = 0; i < asset.categories.Count; ++i)
{
var category = asset.categories[i];
var newCategory = new SpriteLibCategoryOverride()
{
overrideEntries = new List<SpriteCategoryEntryOverride>(category.categoryList.Count),
name = category.name,
entryOverrideCount = 0,
fromMain = false
};
convertAsset.library.Add(newCategory);
for (int j = 0; j < category.categoryList.Count; ++j)
{
newCategory.overrideEntries.Add(new SpriteCategoryEntryOverride()
{
name = category.categoryList[j].name,
sprite = null,
fromMain = false,
spriteOverride = category.categoryList[j].sprite
});
}
}
SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(convertAsset, convertFileName);
}
}
AssetDatabase.Refresh();
}
}
internal class SpriteLibrarySourceAssetPostProcessor: AssetPostprocessor
{
void OnPreprocessAsset()
{
if (assetImporter is SpriteLibrarySourceAssetImporter)
{
var obj = SpriteLibrarySourceAssetImporter.LoadSpriteLibrarySourceAsset(assetPath);
if (obj != null)
{
SpriteLibraryAsset mainLibraryAsset = null;
var mainLibraryAssetAssetPath = AssetDatabase.GUIDToAssetPath(obj.primaryLibraryID);
mainLibraryAsset = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(mainLibraryAssetAssetPath);
var so = new SerializedObject(obj);
var library = so.FindProperty("m_Library");
SpriteLibraryDataInspector.UpdateLibraryWithNewMainLibrary(mainLibraryAsset, library);
if (so.hasModifiedProperties)
{
so.ApplyModifiedPropertiesWithoutUndo();
SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(obj, assetPath);
}
}
}
}
}
}

View File

@@ -0,0 +1,114 @@
using System;
using UnityEditor.AssetImporters;
using UnityEngine;
using UnityEngine.U2D.Animation;
using Object = UnityEngine.Object;
namespace UnityEditor.U2D.Animation
{
[CustomEditor(typeof(SpriteLibrarySourceAssetImporter))]
internal class SpriteLibrarySourceAssetImporterInspector : ScriptedImporterEditor
{
private SerializedProperty m_PrimaryLibraryGUID;
private SerializedProperty m_Library;
private SpriteLibraryAsset m_MainSpriteLibraryAsset;
private SpriteLibraryDataInspector m_SpriteLibraryDataInspector;
public override void OnEnable()
{
base.OnEnable();
m_PrimaryLibraryGUID = extraDataSerializedObject.FindProperty("m_PrimaryLibraryGUID");
if (!m_PrimaryLibraryGUID.hasMultipleDifferentValues && !string.IsNullOrEmpty(m_PrimaryLibraryGUID.stringValue))
{
var assetPath = AssetDatabase.GUIDToAssetPath(m_PrimaryLibraryGUID.stringValue);
m_MainSpriteLibraryAsset = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(assetPath);
}
m_Library = extraDataSerializedObject.FindProperty("m_Library");
m_SpriteLibraryDataInspector = new SpriteLibraryDataInspector(extraDataSerializedObject, m_Library);
}
protected override Type extraDataType => typeof(SpriteLibrarySourceAsset);
protected override void InitializeExtraDataInstance(Object extraTarget, int targetIndex)
{
var obj = SpriteLibrarySourceAssetImporter.LoadSpriteLibrarySourceAsset(((AssetImporter) targets[targetIndex]).assetPath);
if (obj != null)
{
var extraTargetSourceAsset = extraTarget as SpriteLibrarySourceAsset;
extraTargetSourceAsset.library = obj.library;
extraTargetSourceAsset.primaryLibraryID = obj.primaryLibraryID;
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
extraDataSerializedObject.Update();
DoMainAssetGUI();
DoLibraryGUI();
serializedObject.ApplyModifiedProperties();
extraDataSerializedObject.ApplyModifiedProperties();
ApplyRevertGUI();
}
protected override void Apply()
{
base.Apply();
for (int i = 0; i < targets.Length; i++)
{
string path = ((AssetImporter)targets[i]).assetPath;
var sourceAsset = (SpriteLibrarySourceAsset) extraDataTargets[i];
SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(sourceAsset, path);
}
}
void DoMainAssetGUI()
{
EditorGUI.BeginChangeCheck();
if (m_PrimaryLibraryGUID.hasMultipleDifferentValues)
EditorGUI.showMixedValue = true;
m_MainSpriteLibraryAsset = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(AssetDatabase.GUIDToAssetPath(m_PrimaryLibraryGUID.stringValue));
m_MainSpriteLibraryAsset = EditorGUILayout.ObjectField(Style.mainAssetLabel, m_MainSpriteLibraryAsset, typeof(SpriteLibraryAsset), false) as SpriteLibraryAsset;
if (EditorGUI.EndChangeCheck())
{
m_PrimaryLibraryGUID.stringValue = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_MainSpriteLibraryAsset));
SpriteLibraryDataInspector.UpdateLibraryWithNewMainLibrary(m_MainSpriteLibraryAsset, m_Library);
serializedObject.ApplyModifiedProperties();
}
EditorGUI.showMixedValue = false;
}
void DoLibraryGUI()
{
m_SpriteLibraryDataInspector.OnGUI();
}
public override bool showImportedObject
{
get { return false; }
}
static class Style
{
public static GUIContent mainAssetLabel = new GUIContent("Main Library");
}
}
internal class CreateSpriteLibrarySourceAsset : ProjectWindowCallback.EndNameEditAction
{
public override void Action(int instanceId, string pathName, string resourceFile)
{
var asset = ScriptableObject.CreateInstance<SpriteLibrarySourceAsset>();
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new Object[] { asset }, pathName, true);
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
}
[MenuItem("Assets/Create/2D/Sprite Library Asset", priority = 9)]
static private void CreateSpriteLibrarySourceAssetMenu()
{
var action = ScriptableObject.CreateInstance<CreateSpriteLibrarySourceAsset>();
var icon = IconUtility.LoadIconResource("Sprite Library", "Icons/Light", "Icons/Dark");
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, action, "SpriteLib.spriteLib", icon, null);
}
}
}