-
Notifications
You must be signed in to change notification settings - Fork 40
Description
Not sure HOW it happened, but assets that are of the wrong type can be stored and remain in the item list
This is because
[SerializeField] protected List items = new List();
is not using the type specified in the generic class.
Unless there is a reason why ScriptableObjectCollection should remain as a valid implementation, I suggest marking it as abstract and using some deference functions to make sure that only ScriptableObjectCollection is responsible for handling more type specific code.
Going forward, I would suggest also marking ScriptableObjectCollection as abstract
and adding the type specific list in the generated code of the Collection in question.
This would then cause some compile issues for previously existing Collections (unless they can be found and upgraded somehow), but this would be a trivial fix to apply.
public class __TYPE__Collection : ScriptableObjectCollection<__TYPE__>
{
[SerializeField] protected List<__TYPE__> items = new List<__TYPE__>();
}
Also to resolve any desynchronization, perhaps a function like
#if UNITY_EDITOR
public override void Synchronize()
{
var newList = new List<ObjectType>();
// purge all invalid entries, this calls GetEnumerator which skips invalid entries
using (var enumerator = GetEnumerator())
{
while (enumerator.MoveNext())
{
var item = enumerator.Current;
newList.Add(item);
}
}
// add any missing, but existing entries
var guids = AssetDatabase.FindAssets("t:" + typeof(ObjectType));
foreach (var guid in guids)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var asset = AssetDatabase.LoadAssetAtPath<ObjectType>(path);
if (newList.Contains(asset)) continue;
newList.Add(asset);
}
// replace the items list
// as the Synchronization was more type specific
// items = newList, does not work without more steps... unless items is also new List<ObjectType>
items.Clear();
items.AddRange(newList);
}
#endif