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
2 changes: 1 addition & 1 deletion Scripts/Editor/Core/EditorBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ static EditorBehaviour()

private static void OnPlayModeStateChanged(PlayModeStateChange playModeStateChange)
{
if (playModeStateChange == PlayModeStateChange.EnteredPlayMode)
if (playModeStateChange == PlayModeStateChange.ExitingEditMode)
{
CollectionsRegistry.Instance.RemoveNonAutomaticallyInitializedCollections();
}
Expand Down
6 changes: 2 additions & 4 deletions Scripts/Editor/Core/SOCSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,8 @@ public CollectionSettings GetOrCreateCollectionSettings(ScriptableObjectCollecti
string path = AssetDatabase.GetAssetPath(collection);
AssetImporter importer = AssetImporter.GetAtPath(path);

string collectionSettingsData = importer.userData;

CollectionSettings collectionSetting;
if (string.IsNullOrEmpty(collectionSettingsData))
if (importer == null || string.IsNullOrEmpty(importer.userData))
{
collectionSetting = new CollectionSettings(collection);
}
Expand Down Expand Up @@ -302,4 +300,4 @@ public void SaveCollectionSettings(ScriptableObjectCollection collection, bool f
settings.Save();
}
}
}
}
108 changes: 100 additions & 8 deletions Scripts/Editor/CustomEditors/CollectionCustomEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,57 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)
}
);


List<ScriptableObjectCollection> possibleAnotherCollections = GetPossibleAnotherCollections();

if (possibleAnotherCollections.Count > 0)
{
foreach (ScriptableObjectCollection scriptableObjectCollection in possibleAnotherCollections)
{
if (scriptableObjectCollection == collection)
continue;

menu.AddItem(
new GUIContent($"Move to {(AssetDatabase.GetAssetPath(scriptableObject).Replace("/","\\").Replace("Assets", "").Replace(".asset", ""))}"),
false,
() =>
{
if (selectedItemsCount > 0)
{
if (!EditorUtility.DisplayDialog($"Move {collectionItemListView.selectedIndices.Count()} Items",
$"Are you sure you want to move {collectionItemListView.selectedIndices.Count()} items, from {AssetDatabase.GetAssetPath(collection)} to {AssetDatabase.GetAssetPath(scriptableObject)}", "Yes", "No"))
{
return;
}

List<ScriptableObject> moveItems =
new List<ScriptableObject>();
foreach (int selectedIndex in collectionItemListView.selectedIndices)
{
moveItems.Add(filteredItems[selectedIndex]);
}

foreach (ScriptableObject item in moveItems)
{
MoveItem(item, scriptableObjectCollection);
}

}
else
{
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);
}
}
);
}
}

menu.AddSeparator("");
menu.AddItem(
new GUIContent("Select Asset"),
Expand All @@ -840,9 +891,41 @@ private void ShowOptionsForIndex(MouseUpEvent evt, int targetIndex)
}
);

if (selectedItemsCount == 1)
{
menu.AddItem(
new GUIContent("Rename Asset"),
false,
() =>
{
RenameItemAtIndex(collectionItemListView.selectedIndices.First());
}
);
}

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);

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

ReloadFilteredItems();
}

private List<ScriptableObjectCollection> GetPossibleAnotherCollections()
{
CollectionsRegistry.Instance.TryGetCollectionsOfItemType(collection.GetItemType(), out List<ScriptableObjectCollection> collections);
return collections;
}

private void SelectItemAtIndex(params int[] index)
{
Object[] selectedObjects = new Object[index.Length];
Expand Down Expand Up @@ -885,7 +968,7 @@ private void RenameItemAtIndex(MouseDownEvent evt, int targetIndex)

private void RenameItemAtIndex(int targetIndex)
{
ClearCurrentRenamingItem();
ClearCurrentRenamingItem(false);

Undo.RecordObject(filteredItems[targetIndex], "Rename Item");
VisualElement targetElement = collectionItemListView.GetRootElementForIndex(targetIndex);
Expand All @@ -895,19 +978,24 @@ private void RenameItemAtIndex(int targetIndex)
currentRenamingLabel.style.display = DisplayStyle.None;

currentRenamingTextField = targetElement.Q<TextField>();
currentRenamingTextField.RegisterCallback<FocusOutEvent>(OnRenamingAssetLostFocus);
currentRenamingTextField.RegisterValueChangedCallback(_ => OnFinishRenamingItem(targetIndex));

currentRenamingTextField.SetValueWithoutNotify(currentRenamingLabel.text);
currentRenamingTextField.style.display = DisplayStyle.Flex;
currentRenamingTextField.SelectAll();
currentRenamingTextField.Focus();
collectionItemListView.ClearSelection();

currentRenamingTextField.schedule.Execute(() =>
{
currentRenamingTextField.SelectAll();
currentRenamingTextField.RegisterCallback<FocusOutEvent>(OnRenamingAssetLostFocus);
currentRenamingTextField.RegisterValueChangedCallback(_ => OnFinishRenamingItem(targetIndex));
}).ExecuteLater(0);
}

private void OnRenamingAssetLostFocus(FocusOutEvent evt)
{
ClearCurrentRenamingItem();
ClearCurrentRenamingItem(false);
}

private void OnFinishRenamingItem(int targetIndex)
Expand All @@ -929,18 +1017,22 @@ private void OnFinishRenamingItem(int targetIndex)
AssetDatabase.SaveAssetIfDirty(asset);
}

ClearCurrentRenamingItem();
ClearCurrentRenamingItem(true);
}

private void ClearCurrentRenamingItem()
private void ClearCurrentRenamingItem(bool renamedSuccessfully)
{
if (currentRenamingTextField == null)
return;

currentRenamingTextField.UnregisterCallback<FocusOutEvent>(OnRenamingAssetLostFocus);
currentRenamingTextField.style.display = DisplayStyle.None;
currentRenamingLabel.style.display = DisplayStyle.Flex;
currentRenamingLabel.text = currentRenamingTextField.text;
currentRenamingTextField.SetValueWithoutNotify("");
if (renamedSuccessfully)
{
currentRenamingLabel.text = currentRenamingTextField.text;
currentRenamingTextField.SetValueWithoutNotify("");
}
currentRenamingLabel = null;
currentRenamingTextField = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ private void Initialize(SerializedProperty property)
if (initializedPropertiesPaths.Contains(property.propertyPath))
return;

ValidateIndirectReferencesInProperty(property);

Type arrayOrListType = fieldInfo.FieldType.GetArrayOrListType();
Type itemType = arrayOrListType ?? fieldInfo.FieldType;

Expand Down Expand Up @@ -297,5 +299,46 @@ private void Initialize(SerializedProperty property)
labelStyle = assetLabelStyle;
initializedPropertiesPaths.Add(property.propertyPath);
}

private void ValidateIndirectReferencesInProperty(SerializedProperty property)
{
SerializedProperty indirectReferencesProperty = property.FindPropertyRelative(ITEMS_PROPERTY_NAME);

bool changed = false;
for (int i = indirectReferencesProperty.arraySize - 1; i >= 0; i--)
{
SerializedProperty elementProperty = indirectReferencesProperty.GetArrayElementAtIndex(i);

long collectionGUIDValueA = elementProperty.FindPropertyRelative(COLLECTION_GUID_VALUE_A).longValue;
long collectionGUIDValueB = elementProperty.FindPropertyRelative(COLLECTION_GUID_VALUE_B).longValue;
LongGuid collectionGUID = new(collectionGUIDValueA, collectionGUIDValueB);

long itemGUIDValueA = elementProperty.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_A).longValue;
long itemGUIDValueB = elementProperty.FindPropertyRelative(COLLECTION_ITEM_GUID_VALUE_B).longValue;
LongGuid itemGUID = new(itemGUIDValueA, itemGUIDValueB);

bool validReference = false;
if(CollectionsRegistry.Instance.TryGetCollectionByGUID(collectionGUID, out ScriptableObjectCollection collection))
{
if (collection.TryGetItemByGUID(itemGUID, out _))
{
validReference = true;
}
}

if (!validReference)
{
indirectReferencesProperty.DeleteArrayElementAtIndex(i);
changed = true;
}
}

if (changed)
{
indirectReferencesProperty.serializedObject.ApplyModifiedProperties();
}
}


}
}
11 changes: 8 additions & 3 deletions Scripts/Runtime/Core/CollectionItemIndirectReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public TObject Ref

private bool TryResolveReference(out TObject result)
{
if (CollectionsRegistry.Instance.TryGetCollectionByGUID(CollectionGUID, out ScriptableObjectCollection<TObject> collection))
if (CollectionsRegistry.Instance.TryGetCollectionByGUID(CollectionGUID, out ScriptableObjectCollection collection))
{
if (collection.TryGetItemByGUID(CollectionItemGUID, out ScriptableObject item))
{
Expand All @@ -103,8 +103,13 @@ private bool TryResolveReference(out TObject result)

if (!string.IsNullOrEmpty(itemLastKnownName))
{
if(collection.TryGetItemByName(itemLastKnownName, out result))
if(collection.TryGetItemByName(itemLastKnownName, out ScriptableObject possibleResult))
{
result = possibleResult as TObject;
if (result == null)
{
return false;
}
SetCollectionItem(result);
return true;
}
Expand Down Expand Up @@ -148,4 +153,4 @@ public void SetCollection(ScriptableObjectCollection targetCollection)
collectionLastKnowName = targetCollection.name;
}
}
}
}
9 changes: 8 additions & 1 deletion Scripts/Runtime/Core/CollectionItemPicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ public List<TItemType> Items

for (int i = 0; i < indirectReferences.Count; i++)
{
cachedItems.Add(indirectReferences[i].Ref);
CollectionItemIndirectReference<TItemType> collectionItemIndirectReference = indirectReferences[i];
if (!collectionItemIndirectReference.IsValid() || collectionItemIndirectReference.Ref == null)
{
indirectReferences.RemoveAt(i);
continue;
}

cachedItems.Add(collectionItemIndirectReference.Ref);
}

isDirty = false;
Expand Down
Loading