Skip to content

Type Specific ScriptableObjectCollection can contain wrong type #85

@FreezyExp

Description

@FreezyExp

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions