Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [2.3.9] - 19/02/2025
## Changed
- Added some general fixes to validate Collection and Items have unique `LongGuid`
- Fixed issues when after some operation with the context menu on the CollectionEditor items would not refresh properly
- Fixed issue when moving items between collection would not generate unique names
- Removed the post processing of assets that tried to assign items to collections automatically, since this was causing issue when duplicating collections, everyting now is done on the collection
- Overall code improvement and organization

## Added
- Added new Context Menu for moving items between collections
- Added the new PropertyDrawer that shows what Collection every item belongs to
- Added a few more Confirmation dialog when detecting items that looks wrong


## [2.3.8] - 30/01/2025
## Changed
Expand Down Expand Up @@ -612,6 +625,7 @@ public bool IsValidConsumable(Consumable consumable)
### Added
- First initial working version

[2.3.9]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.9
[2.3.8]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.8
[2.3.7]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.7
[2.3.6]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v2.3.6
Expand Down
66 changes: 25 additions & 41 deletions Scripts/Editor/CustomEditors/CollectionCustomEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

namespace BrunoMikoski.ScriptableObjectCollections
{

[CustomEditor(typeof(ScriptableObjectCollection), true)]
public class CollectionCustomEditor : Editor
{
Expand Down Expand Up @@ -394,6 +393,12 @@ protected virtual void OnEnable()
{
collection = (ScriptableObjectCollection)target;

if (!CollectionsRegistry.Instance.HasUniqueGUID(collection))
{
collection.GenerateNewGUID();
collection.Clear();
}

if (!CollectionsRegistry.Instance.IsKnowCollection(collection))
CollectionsRegistry.Instance.ReloadCollections();

Expand Down Expand Up @@ -626,10 +631,10 @@ private bool IsAddressableAsset(ScriptableObject target)
#endif
}

private ScriptableObject AddNewItemOfType(Type targetType, bool autoFocusForRename = true)
private ScriptableObject AddNewItemOfType(Type targetType,string assetName = "", bool autoFocusForRename = true)
{
Undo.IncrementCurrentGroup();
ScriptableObject newItem = collection.AddNew(targetType);
ScriptableObject newItem = collection.AddNew(targetType, assetName);
Undo.RegisterCreatedObjectUndo(newItem, "Create New Item");
Undo.RecordObject(collection, "Add New Item");
Undo.SetCurrentGroupName($"Created new item {newItem.name}");
Expand Down Expand Up @@ -792,10 +797,12 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)
{
DuplicateItem(item, false);
}
ReloadFilteredItems();
}
else
{
DuplicateItem(targetIndex);
ReloadFilteredItems();
}
}
);
Expand Down Expand Up @@ -825,6 +832,7 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)
{
RemoveItemAtIndex(collection.IndexOf(item), result == 2);
}
ReloadFilteredItems();
}
else
{
Expand All @@ -837,6 +845,7 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)
}

RemoveItemAtIndex(filteredItems.Count - 1, result == 2);
ReloadFilteredItems();
}
}
);
Expand Down Expand Up @@ -872,19 +881,20 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)

foreach (ScriptableObject item in moveItems)
{
MoveItem(item, scriptableObjectCollection);
SOCItemUtility.MoveItem(item as ISOCItem, scriptableObjectCollection);
}
ReloadFilteredItems();

}
else
{
if (!EditorUtility.DisplayDialog($"Move Item",
if (!EditorUtility.DisplayDialog("Move Item",
$"Are you sure you want to move {filteredItems[^1].name}, from {AssetDatabase.GetAssetPath(collection)} to {AssetDatabase.GetAssetPath(scriptableObject)}", "Yes", "No"))
{
return;
}

MoveItem(filteredItems[targetIndex], scriptableObjectCollection);
SOCItemUtility.MoveItem(filteredItems[targetIndex], scriptableObjectCollection);
ReloadFilteredItems();
}
}
);
Expand Down Expand Up @@ -923,38 +933,6 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)
menu.ShowAsContext();
}

private void MoveItem(ScriptableObject item, ScriptableObjectCollection targetCollection)
{
Undo.RecordObject(collection, "Move Item");
Undo.RecordObject(targetCollection, "Move Item");

collection.Remove(item);
targetCollection.Add(item);

string itemPath = AssetDatabase.GetAssetPath(item);
string targetCollectionPath = AssetDatabase.GetAssetPath(targetCollection);

if (!string.IsNullOrEmpty(itemPath) && !string.IsNullOrEmpty(targetCollectionPath))
{
string directory = Path.GetDirectoryName(targetCollectionPath);

string itemsFolderPath = Path.Combine(directory, "Items");
bool hasItemsFolder = AssetDatabase.IsValidFolder(itemsFolderPath);

string finalDirectory = hasItemsFolder ? itemsFolderPath : directory;
string fileName = Path.GetFileName(itemPath);

string newPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(finalDirectory, fileName));

AssetDatabase.MoveAsset(itemPath, newPath);
}

AssetDatabase.SaveAssets();
AssetDatabase.Refresh();

ReloadFilteredItems();
}

private List<ScriptableObjectCollection> GetPossibleAnotherCollections()
{
CollectionsRegistry.Instance.TryGetCollectionsOfItemType(collection.GetItemType(), out List<ScriptableObjectCollection> collections);
Expand All @@ -980,7 +958,14 @@ private void DuplicateItem(int index, bool showRenameAfter = true)
private void DuplicateItem(ScriptableObject source, bool showRenameAfter)
{
CopyCollectionItemUtility.SetSource(source);
ScriptableObject newItem = AddNewItemOfType(source.GetType(), false);

string path = AssetDatabase.GetAssetPath(source);
string directory = Path.GetDirectoryName(path);
string fileName = $"{source.name} (Clone)";

fileName = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(directory, $"{fileName}.asset"));

ScriptableObject newItem = AddNewItemOfType(source.GetType(), Path.GetFileNameWithoutExtension(fileName), false);
CopyCollectionItemUtility.ApplySourceToTarget(newItem);

if (showRenameAfter)
Expand All @@ -990,7 +975,6 @@ private void DuplicateItem(ScriptableObject source, bool showRenameAfter)
}
else
{
AssetDatabaseUtils.RenameAsset(newItem, $"{source.name} (Copy)");
AssetDatabase.SaveAssetIfDirty(newItem);
ReloadFilteredItems();
}
Expand Down
45 changes: 45 additions & 0 deletions Scripts/Editor/CustomEditors/MoveToCollectionWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace BrunoMikoski.ScriptableObjectCollections
{
public class MoveToCollectionWindow : EditorWindow
{
private List<ISOCItem> itemsToMove;
private List<ScriptableObjectCollection> availableCollections;

public static void ShowWindow(List<ISOCItem> items, List<ScriptableObjectCollection> collections)
{
MoveToCollectionWindow window = GetWindow<MoveToCollectionWindow>("Move to Collection");
window.itemsToMove = items;
window.availableCollections = collections;
window.ShowPopup();
}

private void OnGUI()
{
EditorGUILayout.LabelField("Select a Collection to Move Items", EditorStyles.boldLabel);

if (availableCollections == null || availableCollections.Count == 0)
{
EditorGUILayout.LabelField("No available collections.");
return;
}

foreach (ScriptableObjectCollection collection in availableCollections)
{
if (GUILayout.Button(collection.name))
{
foreach (ISOCItem item in itemsToMove)
{
SOCItemUtility.MoveItem(item, collection);
EditorUtility.SetDirty(collection);
}

Close();
}
}
}
}
}
3 changes: 3 additions & 0 deletions Scripts/Editor/CustomEditors/MoveToCollectionWindow.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public static AssetDeleteResult OnWillDeleteAsset(string targetAssetPath, Remove
if (socItem == null)
return AssetDeleteResult.DidNotDelete;

if (socItem.Collection == null)
return AssetDeleteResult.DidNotDelete;

socItem.Collection.Remove(collectionItem);
return AssetDeleteResult.DidNotDelete;
}
Expand All @@ -42,4 +45,4 @@ public static AssetDeleteResult OnWillDeleteAsset(string targetAssetPath, Remove
}

}
}
}
44 changes: 21 additions & 23 deletions Scripts/Editor/Processors/CollectionsAssetsPostProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,21 @@ static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAsse
ScriptableObject collectionItem =
AssetDatabase.LoadAssetAtPath<ScriptableObject>(importedAssetPath);

if (collectionItem != null)
if (collectionItem == null)
{
if (collectionItem is ISOCItem socItem)
{
if (socItem.Collection == null)
{
continue;
}
continue;
}

if (collectionItem is not ISOCItem socItem)
{
continue;
}

if (!socItem.Collection.Contains(collectionItem))
{
if (socItem.Collection.TryGetItemByGUID(socItem.GUID, out _))
{
Debug.LogWarning(
$"Collection already contains one item with the same GUID" +
$" ({socItem.GUID}) but different name ({socItem.name}), generating new GUID");
socItem.GenerateNewGUID();
}

socItem.Collection.Add(collectionItem);
Debug.Log($"{collectionItem.name} has collection assigned "
+ $"{socItem.Collection} but its missing from collection list, adding it");
}
}
if (!CollectionsRegistry.Instance.HasUniqueGUID(socItem))
{
socItem.GenerateNewGUID();
socItem.ClearCollection();
Debug.LogWarning($"Item {socItem} GUID was not unique, generating a new one and clearing the collection");
}
}

Expand All @@ -64,6 +55,13 @@ static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAsse
if (collection == null)
continue;

if (!CollectionsRegistry.Instance.HasUniqueGUID(collection))
{
collection.GenerateNewGUID();
collection.Clear();
Debug.LogWarning($"Collection {collection} GUID was not unique, generating a new one, and clearing the items");
}

if (!CollectionsRegistry.Instance.IsKnowCollection(collection))
{
RefreshRegistry();
Expand Down Expand Up @@ -95,4 +93,4 @@ static void OnAfterScriptsReloading()
RefreshRegistryAfterRecompilation = false;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using UnityEditor;
using UnityEngine;

namespace BrunoMikoski.ScriptableObjectCollections.Picker
{
[CustomPropertyDrawer(typeof(CollectionReferenceLongGuidAttribute))]
public class CollectionReferenceLongGuidDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
LongGuid collectionGUID = (LongGuid)property.boxedValue;

ScriptableObjectCollection collection = null;
if (collectionGUID.IsValid())
{
collection = CollectionsRegistry.Instance.GetCollectionByGUID(collectionGUID);
}

EditorGUI.BeginDisabledGroup(true);
EditorGUI.ObjectField(position, "Collection", collection, typeof(ScriptableObjectCollection), false);
EditorGUI.EndDisabledGroup();
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading