Giter Site home page Giter Site logo

brunomikoski / scriptableobjectcollection Goto Github PK

View Code? Open in Web Editor NEW
496.0 496.0 34.0 1.19 MB

A library to help improve the usability of Unity3D Scriptable Objects by grouping them into a collection and providing easy access through code or user-friendly inspectors!

License: MIT License

C# 100.00%
assets assets-management database scriptableobjects tools unity3d

scriptableobjectcollection's Introduction

Hi 👋, I'm Bruno Mikoski

I have been converting 🍕 into 🕹 in the past 15 years.

Most of my works are related to this

Android iOS CSharp Continuous Integration git unity

Here's some things about me

✨ Tools I'm most proud of ✨







🕹 Latest Projects 🕹

Project Platforms
Android iOS
Android iOS
Nintendo Switch
More on brunomikoski.myportfolio.com

scriptableobjectcollection's People

Contributors

brunomikoski avatar brunomikoskib avatar chimpdw avatar freezyexp avatar gsimone avatar ikeikep avatar ovieira avatar ovieira-miniclip avatar roytheunissen avatar thundernerd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scriptableobjectcollection's Issues

Exception at Collection creation - SOCSettings.GetOrCreateCollectionSettings

I get this twice on Collection creation every time - at the moment I don't see any bad effects and the Collection are working etc. Haven't looked in to it.

[Exception] NullReferenceException: Object reference not set to an instance of an object
SOCSettings.GetOrCreateCollectionSettings() at Packages/[email protected]/Scripts/Editor/Core/SOCSettings.cs:265

SOCSettings.GetParentFolderPathForCollection() at Packages/[email protected]/Scripts/Editor/Core/SOCSettings.cs:169

CollectionCustomEditor.UpdateGenerateStaticFileButtonState() at Packages/[email protected]/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs:465

CollectionCustomEditor.CreateInspectorGUI() at Packages/[email protected]/Scripts/Editor/CustomEditors/CollectionCustomEditor.cs:163

InspectorElement.CreateInspectorElementFromEditor() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Inspector/InspectorElement.cs:711

InspectorElement.Reset() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Inspector/InspectorElement.cs:297

InspectorElement.ExecuteDefaultActionAtTarget() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Inspector/InspectorElement.cs:348

CallbackEventHandler.HandleEvent() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:200

CallbackEventHandler.HandleEventAtTargetPhase() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:153

SerializedObjectBindingContext.SendBindingEvent[TEventType]() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:83

SerializedObjectBindingContext.BindTree() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:101

SerializedObjectBindingContext.ContinueBinding() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:38

SerializedObjectBindingContext.Bind() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:29

DefaultSerializedObjectBindingImplementation.Bind() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:864

BindingExtensions.Bind() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingsInterface.cs:52

UnityEditor.UIElements.InspectorElement..ctor() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Inspector/InspectorElement.cs:218

EditorElement.Init() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Inspector/EditorElement.cs:125

UnityEditor.UIElements.EditorElement..ctor() at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Inspector/EditorElement.cs:94

EditorUIServiceImpl.CreateEditorElement() at /Users/bokken/build/output/unity/unity/Modules/UIServiceEditor/EditorUIService.cs:33

PropertyEditor.DrawEditors() at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/PropertyEditor.cs:1749

PropertyEditor.RebuildContentsContainers() at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/PropertyEditor.cs:896

InspectorWindow.RedrawFromNative() at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/InspectorWindow.cs:156

Handle destroyed Collectables

Steps to reproduce:
▶‎‎⠀‎Create a new Collection
▶⠀Add new Collectables to it, of the base type
▶⠀Create a GameObject "A", with a script with a Serialised variable of the type of the Collectable
▶⠀Go to the Collectable class file, change it to abstract
▶⠀Select the Collection Scriptable Object, should see:

ArgumentException: Object at index 0 is null

▶⠀Select GameObject "A", should see:

MissingReferenceException: The object of type 'CollectableScriptableObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.

Custom Folders for Collection Items

Rather than having all SO created under the same named folder, I'd like to have each collection use it's own folder.

That way I can name the SO items without prefix and they are grouped in different folders.

For the moment I've added to top of ScriptableObjectCollection

        public string itemFolderName = "Items";

and line 134 change to

string parentFolderPath = Path.Combine(assetPath, itemFolderName);

which allows me to set custom folder for custom Collections

    public class PlayerGameEventCollection : AtomEventCollection<PlayerGameEvent>
    {
        PlayerGameEventCollection() { itemFolderName = "Player"; }
    }

Not sure whether this will break things - presume SO are found via reference from creation?

I found one more hardcoded "Items" in the ScriptableObjectCollectionUtility which seems to have only one reference from CreateCollectionWizard.cs - so just used via Wizard and can be changed after.

Screen Shot 2024-05-18 at 17 11 26

Collections added in runtime being removed on OnPlayModeStateChanged

Collections marked to not load automatically, are removed on OnPlayModeStateChanged when running from the Editor.
The problem is that when this event is fired, plenty of runtime initialisation code has already ran, initialisations that could have added collections to the registry - resulting in them being automatically removed afterwards.

Collection Item Property Drawer - NullReferenceException when no collection

I've been doing some debug of Items and pulling them into a dictionary at runtime. Don't know how to block the custom SOC drawer (?) but the NullReferenceException has been popping up fairly regularly anyway during editing - it hasn't been a problem outside of runtime as it seems to get generated when the Item is first created but then the collection registry eventually catches up.

But as I'm forced to view the Items using the drawer and some of them seem to have issues with registry I've added this line and everything seems to work fine now.

Thought I'd add an issue as the Exception occurs for me almost every time I create a new Item. But in this case it was actually corrupting the whole Inspector during Editor runtime.

Line 249 SOCSettings.cs edit

        public bool GetEnforceIndirectAccess(ScriptableObjectCollection collection)
        {
            if (EditorApplication.isPlaying && collection == null) return false;
            return GetOrCreateCollectionSettings(collection).EnforceIndirectAccess;
        }


Screen Shot 2024-06-07 at 09 55 49

Naming consistency

Naming format differ in:
CollectableScriptableObject
ScriptableObjectCollection

Suggestion: CollectionScriptableObject

Progress Bar "Animatable"

Would be nice to be able to animate the progress bar via mechanim system, that way we can integrate tweens animations in the Timeline for example. This would be super powerful.

Version mismatch

Git tag v1.0.1
package.json version: 1.0.0

To fix: bump package.json version and re-tag v1.0.1.

The openupm build-pipelines will catch up in 10mins.

ArgumentNullException when leaving Play Mode

Unity Version: 2021.3.11f1
SOC Version: 1.9.6
Addressables Version: 1.19.19

Steps to reproduce:

  1. Create a collection
  2. Mark Automatically Loaded as false
  3. Mark the Collection as Addressable Asset
  4. Enter Play Mode
  5. Load collection via Addressable
  6. Exit Play Mode

ArgumentNullException: Value cannot be null. Parameter name: collection System.Collections.Generic.List``1[T]..ctor (System.Collections.Generic.IEnumerable``1[T] collection) (at <612a2c65aaf843d698f8d38b2ad7654a>:0) BrunoMikoski.ScriptableObjectCollections.ScriptableObjectCollection.PrepareForEditorMode () (at Library/PackageCache/[email protected]/Scripts/Runtime/Core/ScriptableObjectCollection.cs:392) BrunoMikoski.ScriptableObjectCollections.CollectionsRegistry.PrepareForEditorMode () (at Library/PackageCache/[email protected]/Scripts/Runtime/Core/CollectionsRegistry.cs:306) BrunoMikoski.ScriptableObjectCollections.EditorBehaviour.OnPlayModeStateChanged (UnityEditor.PlayModeStateChange playModeStateChange) (at Library/PackageCache/[email protected]/Scripts/Editor/Core/EditorBehaviour.cs:25) UnityEditor.EditorApplication.Internal_PlayModeStateChanged (UnityEditor.PlayModeStateChange state) (at /Users/bokken/buildslave/unity/build/Editor/Mono/EditorApplication.cs:438)
SOCAddressablesTestProject.zip

Rename CollectionItem too hard to find

Hi, I can't see anyway to easily rename the SO after they have been created - as per when you first create them and the object name is highlighted and editable.

EDIT - Found it F2 after looking through code - too hidden for me (on a Mac too so not instinctual!)

Added Rename Asset to ShowOptionsForIndex line 724 of CollectionCustomEditor

            menu.AddSeparator("");
            menu.AddItem(
                new GUIContent("Rename Asset"),
                false,
                () => { RenameItemAtIndex(targetIndex); }
            );

Request: Delete Collection

I want to easily delete a new collection, since nowadays we need to delete all the generated files by hand, and manually remove the registry reference.

Using .GetOrAddNew<T> throws a InvalidOperationException if the item does not exist

Like the title says, calling .GetOrAddNew<T> throws an InvalidOperationException if the item does not already exist.
The reason is that it isn't calling FirstOrDefault() but it is calling First().

File: ScriptableObjectCollection.cs
Line: 427-434

public ObjectType GetOrAddNew(string targetName)
{
    ObjectType item = Items.First(o => o.name.Equals(targetName, StringComparison.Ordinal)) as ObjectType;
    if (item != null)
        return item;

    return AddNew(targetName);
}

Workaround:

Use .GetOrAddNew(typeof(...), "...");

Question: How to use it for subclasses of Tile/TileBase?

Hey!

First of all: Thanks for the awesome project. We're currently testing everything and from what I can tell so far, all CollectionItems have to inherit from ScriptableObjectCollectionItem.

What if you want/need to make a collection of TileBase/Tile-subclasses (or any other already existing ScriptableObject class)?
Would that be possible?

Error when leaving the edit drawer open on a script

I have a script with a CollectableScriptableObject variable.
On the editor, I open the edit drawer and if I leave it open when I select another object in the hierarchy, when I come back the scriptable object is broken and throwing an error OnGUI. It seems to only happen when leaving the drawer open.

Bug2.mp4

ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint
Aborting
UnityEngine.GUILayoutGroup.GetNext () (at /Users/bokken/buildslave/unity/build/Modules/IMGUI/LayoutGroup.cs:122)
UnityEngine.GUILayoutUtility.BeginLayoutGroup (UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options, System.Type layoutType) (at /Users/bokken/buildslave/unity/build/Modules/IMGUI/GUILayoutUtility.cs:309)
UnityEditor.EditorGUILayout.BeginVertical (UnityEngine.GUIContent content, UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options) (at /Users/bokken/buildslave/unity/build/Editor/Mono/EditorGUI.cs:9437)
UnityEditor.EditorGUILayout.BeginVertical (UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options) (at /Users/bokken/buildslave/unity/build/Editor/Mono/EditorGUI.cs:9427)
UnityEditor.EditorGUILayout+VerticalScope..ctor (UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options) (at /Users/bokken/buildslave/unity/build/Editor/Mono/EditorGUI.cs:9405)
BrunoMikoski.ScriptableObjectCollections.CollectableScriptableObjectPropertyDrawer.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at Library/PackageCache/com.brunomikoski.scriptableobjectcollection@8f5ee34a96/Scripts/Editor/CollectableScriptableObjectPropertyDrawer.cs:109)
UnityEditor.PropertyDrawer.OnGUISafe (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at /Users/bokken/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyDrawer.cs:23)
UnityEditor.PropertyHandler.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.Rect visibleArea) (at /Users/bokken/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:139)
UnityEditor.GenericInspector.OnOptimizedInspectorGUI (UnityEngine.Rect contentRect) (at /Users/bokken/buildslave/unity/build/Editor/Mono/Inspector/GenericInspector.cs:106)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass58_0.b__0 () (at /Users/bokken/buildslave/unity/build/Editor/Mono/Inspector/InspectorElement.cs:520)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) (at /Users/bokken/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:197)

Error while creating new collection

Just added the package into my project and tried to create a new collection. After that, the collection was not automatically created and I had this exepction:

image

Type Specific ScriptableObjectCollection can contain wrong type

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

Collection Inspector is not updating properly

I have a Collection called "Types", and each type has a list of strengths, weaknesses and immunites of the same type as the collection item.
image
When I try to fill those lists, selecting the item does nothing.

CollectionItem with Generic Inheritance (Unity Atoms)

Hi thanks for this library - trying to use it organise Unity Atoms - starting with Events but probably move on to Variables, Actions, Conditions etc.

I have classes derived from your library with Generics

public class AtomEventCollection<T> : ScriptableObjectCollection<AtomEventItem<T>>    
{    }
public abstract class AtomEventItem<T> : ScriptableObjectCollectionItem
    {
        [SerializeField]
        private AtomEvent<T> _event;
        public AtomEvent<T> Event
        {
            get { return _event; }
            set { _event = value; }
        }

.... this also automatically generates the AtomEvent<T> on creation and nests it under the CollectionItem
public class AtomEventIndirectReference<T> : CollectionItemIndirectReference<AtomEventItem<T>>    {
        public AtomEventIndirectReference() {}
        public AtomEventIndirectReference(AtomEventItem<T> collectionItemScriptableObject) : base(collectionItemScriptableObject) {}
    }

which then get made concrete like

public partial class WorldGameEvent : AtomEventItem<World> { }

public class WorldGameEventCollection : AtomEventCollection<WorldGameEvent> { }

As far as I can tell at this stage this is working.

In order to get this working I've had to make the following edit on line 226 of ScriptableObjectCollection.cs
` // DOESN'T WORK -> if (baseType.IsGenericType && baseType.GetGenericTypeDefinition() == typeof(ScriptableObjectCollection<>))

if (baseType.IsGenericType) // edit mgmhunt`

as it's presuming the Generics are only the ScriptableObjectCollection<>. I couldn't get IsSubClass of (probably to do with Generics again - maybe you've got a cleaner way of fixing this?)

My question is do you foresee issues down the road with this as I'm hoping this library will be broadly useful and not sure what this assumption my cause with other classes?

----- Working so far ----

WorldGameEvent testWorldEvent;
testWorldEvent.Event.Observe().TakeUntilDisable(this).Subscribe(_ => { LoadWorld(defaultWorld); }).AddTo(_subscriptions);
testWorldEvent.Event.Raise();

Screen Shot 2024-05-18 at 09 43 49
Screen Shot 2024-05-18 at 09 46 58

Declaring a `List<>` of a collection item type causes unexpected results.

Declaring a list of a collection item type like this [SerializeField] private List<AudioClipEventId> testList; causes the list dropdown to act weirdly. It seems to incorrectly assume that the collection type is the encapsulating List.

Version is Unity 2021.3.2f1 and it uses the latest version of the ScriptableObjectCollection.

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.