Search Unity

Assets [RELEASED] ScriptableObject Databases

Discussion in 'Works In Progress - Archive' started by icepick912, Dec 31, 2018.

  1. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    704
    Hi, I'm trying to reimport my project and it keeps on getting the following box.
    upload_2019-6-26_6-29-1.png
    It goes on to the infinite loop, keeps on getting this error message and reimport never finishes.
    Is this something caused by this Asset?
     
  2. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    Hrm try deleting the main database collection asset. Or delete and reimport the plugin.
     
  3. DragonFist22

    DragonFist22

    Joined:
    Mar 28, 2018
    Posts:
    14
    Okay, took a little bit to work through it, but I got it installed and created a couple of related databases.

    I was a bit disappointed that there is no way to filter on those relations. In other words, if I have an ItemsCategory database and an Items database and the ItemCategory is a property of the Items, then I'd expect to be able to filter my items by their category. Or by any other similar relation as long as there exists an actual connection like a property pointing to the related scriptable object, etc.

    Otherwise, It is little more than a convenient window to edit items. But one still has to search by name, etc.

    Anyhow, the ability to at least filter by sub-objects or to, say, right-click on a "category", etc. and have an option to create an Item with this category assigned, etc. would make this much more useful.
     
  4. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    On point one it is doable, and I can see the value of it not just for items but for any ScriptableObject, and also for navigating to other databases as well. a very good suggestion, ill look into that for sure. On the second point, if I understand correctly, You wish to be able to create a category for an item while inspecting the item, and not have to jump over to the item category database to do so?

    And this is most definitely a convenience/workflow plugin, but is not only for items. For any ScriptableObject, its just item databases seems to be the best, but also most misleading way for users to relate to it within the context of games. Misleading meaning I have had a few people think its specifically for creating and saving items. This is my fault however since I use items and item attributes almost exclusively in the screenshots.
     
  5. DragonFist22

    DragonFist22

    Joined:
    Mar 28, 2018
    Posts:
    14
    Yeah, I understand that Items is just one use case. But even in other use cases, if there exists a relation, it would likely be useful to take actions based on that relation. But the filtering I think is what be of the most use, as once you have a large number of ScriptableObjects, the difficulty in dealing with them is finding the ones that one needs to edit.

    With such filtering, I could imagine making "category" items that serve no purpose other than organization and with large numbers of objects to sift through, that would have use.
     
  6. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    For sure, I agree. A great suggestion I haven't considered, thank you! I believe I know what your asking for with filtering now and I will get right on it :)

    As with relations between different SciptableObjects that exists within separate, or Sub-Databases, I am thinking maybe a visual identifier of some kind next to variable fields that could indicate extended functionality. From there maybe display a tool tip explaining to the user that there exists right click context menu options perhaps. I think that's the best way start at it until I get a better idea as to what would be intuitive and use the least amount of ui space.

    Again thanks for the contribution DragonFist!
     
  7. thatscraigz

    thatscraigz

    Joined:
    Mar 27, 2015
    Posts:
    100
    Just discovered this asset! So excited to try it out :D

    Thanks for what already looks like great support :D
    -craigz
     
  8. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
  9. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    Got a fully functional filter in there now, filter by any UnityEngine.Object type, including textures, prefabs, ScriptableObjects, any UnityEngine.Object derived type. Automatically finds fields it can use as filters, sorts the filters based on the class they belong to, can add multiple filters for same fields, and disable / enable filtering for each filter.

    ForumImage.png

    Have 2 bugs with pages and filtering to work through, but after that its good to upload.
     
    DungDajHjep likes this.
  10. thatscraigz

    thatscraigz

    Joined:
    Mar 27, 2015
    Posts:
    100
    Wahoo! :D This is rad! :D
     
  11. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    New version with filtering is up now. Let me know if there are any problems.
     
  12. DragonFist22

    DragonFist22

    Joined:
    Mar 28, 2018
    Posts:
    14
    Awesome stuff! I'll definitely put it to use and give any feedback. Very cool to see such immediate response to feedback.
     
    icepick912 likes this.
  13. Andrew900460

    Andrew900460

    Joined:
    Aug 9, 2017
    Posts:
    39
    Just a suggestion, this does get into backbone stuff, but I would like this feature. Right now, there is no way to get the ID of a database asset if all you have is a reference to the scriptable object, and in some cases, I would like to just provide a ScriptableObject reference in a Mono, and then have the power to get the ID of the asset straight from the S.O.

    Obviously, it would be impractical to make a system where I, the user, would have to provide the variable in the S.O. and have it detect the variable and pass in the value. But what would work is if you made a special class that inherited from ScriptableObject that just had basic info like the id and the file name. And all of our, the users, database assets would derive from your "DatabaseObject" class. and that info would be automatically passed in.

    Also, I saw you pushed another update it looks like, I might be getting that soon.
     
  14. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    The only problem i see with that kind of setup is when a ScriptableObject belongs to more than one database. Perhaps ill make a way to search using the DatabaseManager class that would take a ScriptableObject as input, and return a list of databases that contain the object, or return a list of all database ids for a ScriptableObject. Would that be satisfactory?
     
  15. Rafaadfafd

    Rafaadfafd

    Joined:
    Jul 26, 2019
    Posts:
    2
    Hi I have got Sqlite Database for Soccer Game. So I want to remake with your ScriptableObject Database.Can I make this database with your asset?? Have you got any advises ??

    upload_2019-7-26_14-21-34.png
    upload_2019-7-26_14-22-23.png
     
  16. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    If you can code then making your own ScriptableObject is simple read Here. The bare minimum is to know how to create a ScriptableObject in code, and how to create one in the project at the moment. I am thinking of programming a ScriptableObject Creator that would guide non-programmers thru creating and editing ScriptableObjects, or even just as a convenience feature for all users, I know I wouldn't mind creating, and editing them through a menu instead of pure code.

    After you have a ScriptableObject to store the Plugin comes with a wizard to set you up with a database for a ScriptableObject. The database created for any ScriptableObject will include other ScriptableObject Classes that inherit from the original ScriptableObject. After using the Database Creation Wizard, there is an Editor Window that allows a user to create as many ScriptableObjects as one likes, you can use it as an Editor Tool only and just use to it keep everything more centralized, and tidy. However, the plugin also comes with a Runtime DatabaseManager that will allow a user to access their ScriptableObjects and databases through code to do with as one needs.

    In order to get the full benefit of the Plugin I would suggest an intermediate level of Programming knowledge, however if all your looking for is to store data inside the unity enviroment, and don't need to search through the Databases, then the tool should work fine for ya.

    Any specifics i miss, please don't hesitate to ask. Im happy to point you to some information that can get you started if you are interested. Thanks for the interest @Rafaadfafd !
     
  17. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    704
    Hi, I had to remove SODB because it was causing an error and I just tried the latest SODB to see if how it works.
    I installed SODB with just the sample DB that it came with but opening the "Editor Window" takes about a minute.
    Yeah, I have a large number of asset and it seems like it scanning the whole assets.
    I understand that it needs to scan for the first time but closing and opening the window will take a minute every time, and it seems like it scanning every time.

    I thought you implemented caching mechanism, no?
     
  18. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    I think its because of the new filtering system. It scans the scripts for child UnityObject classes. I'm thinking either moving the update to a menu that would make the user responsible for making sure to update when creating and modifying ScriptableObjects, or do it on script recompile, i don't like that latter idea, interferes with workflow. Maybe just make a refresh button in the filtering menu, that would be highlighted if there has been a change. Typically I leave the window open and tabbed somewhere out of the way until i need it, however i can see with many tools, one doesn't want them all open all the time. Ill work on a solution for it, Thank you for letting me know! @chrisk
     
  19. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    704
    I can tab the window to prevent reopening but then it will cause the delay when Unity restarts. I think it's better to have a button to manually rescan from the options menu and cache the information somewhere. Thanks.
     
    DungDajHjep likes this.
  20. hsjaaa

    hsjaaa

    Joined:
    Apr 30, 2016
    Posts:
    29
    Hi there, want to know the way to access database created by this asset using script, is it using Resources.Load or what else?
    And if this database can serve the purpose of serializing SO reference in a GameObject, or in another SO? The default serializing using InstanceID, and it seems InstanceID could change so maybe not a good idea to store that.
     
  21. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    Databases and assets can be retrieved in code by using a 32 bit int key that contains a 16bit database id on the left side, and a 16bit asset id on the right.

    To Serialize Data use the [DatabaseAssetProperty(typeof("DatabaseType"))] Attribute on an int variable like this:

    Code (CSharp):
    1. [System.Serializable]
    2. public class CustomEdtiorTest : MonoBehaviour
    3. {
    4.     public float oneOne;
    5.     [DatabaseAssetProperty(typeof(ItemDatabaseFile))]
    6.     public int[] MiscItemAssets;
    7.  
    8.     public bool toggler;
    9.     public string tester;
    10.  
    11.     [DatabaseAssetProperty(typeof(PrefabDatabaseFile))]
    12.     public int PrefabAssets;
    13.  
    14.     [DatabaseAssetProperty(typeof(ItemDatabaseFile))]
    15.     public int ItemAsset0;
    16.  
    17.     public int flyer;
    18.  
    19.     [DatabaseAssetProperty(typeof(ItemDatabaseFile))]
    20.     public int ItemAsset1;
    21.  
    22.     public void Start()
    23.     {
    24.         Debug.Log("Asset 0:" + MainDatabaseCollection.GetAsset(MiscItemAssets[0]).name);
    25.         Debug.Log("Asset 1:" + MainDatabaseCollection.GetAsset(PrefabAssets).name);
    26.         Debug.Log("Asset 2:" + MainDatabaseCollection.GetAsset(ItemAsset0).name);
    27.         Debug.Log("Asset 3:" + MainDatabaseCollection.GetAsset(ItemAsset1).name);
    28.     }
    29. }
    Here is the above code in the Inspector.


    The ScriptableObject button on the left will navigate to the assets in the Project View.

    This is the selector UI popup interface when a user clicks the Database or Asset drop-downs. It provides an interface for selecting the database or asset data, in this example we already have selected a database, The database data popup is nearly identical.


    The MainDatabaseCollection handles Getting databases and assets using unique 32 bit database ids that contain both a 16 bit database, and a 16 bit asset id. for each ScriptableObject.

    To retrieve data using the 32 bit id use these methods like in the Start() function above.

    Code (CSharp):
    1. /// <summary>
    2. /// A Scriptable object used to keep track of all the databases in the project.
    3. /// </summary>
    4. [System.Serializable]
    5. public class MainDatabaseCollection : ScriptableObject
    6. {
    7.     /// <summary>
    8.     /// Gets all databases of a certain type.
    9.     /// </summary>
    10.     /// <typeparam name="T">The database type to retrieve.</typeparam>
    11.     /// <param name="visibility">Return databasese using a certain visibility specification.
    12.     </param>
    13.     /// <returns>A list of all databases of a specified type, and visibility.</returns>
    14.     public static T[] GetDatabasesOfType<T>(Database.Visibility visibility)
    15.         where T : IDatabaseFile
    16.     { }
    17.  
    18.     /// <summary>
    19.     /// Retrieves a specific database.
    20.     /// </summary>
    21.     /// <param name="id16">Database 16 bit ID.</param>
    22.     /// <returns>Database or null if database does not exist.</returns>
    23.     public static IDatabaseFile GetDatabase(short id16)
    24.     { }
    25.  
    26.     /// <summary>
    27.     /// Retrieves a specific database.
    28.     /// </summary>
    29.     /// <param name="key32">Database 32 bit ID.</param>
    30.     /// <returns>Database or null if database does not exist.</returns>
    31.     public static IDatabaseFile GetDatabase(int key32)
    32.     { }
    33.  
    34.     /// <summary>
    35.     /// Gets an asset using the 32 bit ID
    36.     /// </summary>
    37.     /// <param name="key32">32 bit ID containing both database and asset IDs.</param>
    38.     /// <returns>The specified asset or null if none was found.</returns>
    39.     public static DatabaseAsset GetAsset(int key32)
    40.     { }
    41. }
    The MainDatabaseCollection ScriptableObject is located in every project at 'Plugins/ScriptabelObjectDatabase/Resources'.

    once you have a DatabaseAsset using the MainDatabaseCollection

    Code (CSharp):
    1. public abstract class DatabaseAsset
    2. {
    3.         /// <summary>
    4.         /// The 16 bit database ID.
    5.         /// </summary>
    6.         public short DatabaseID16 { get { return pKey.DatabaseKey; } }
    7.  
    8.         /// <summary>
    9.         /// The 16 bit asset id.
    10.         /// </summary>
    11.         public short AssetKey16 { get { return (short)pKey.AssetKey; } }
    12.  
    13.         /// <summary>
    14.         /// The combined database and asset id wrapped into a 32 bit integer.
    15.         /// </summary>
    16.         public int ID32 { get { return pKey.Key32; } }
    17. }
    Get the DatabaseAsset from a database using

    Code (CSharp):
    1.     /// <summary>
    2.     /// Base database data.
    3.     /// </summary>
    4.     [System.Serializable]
    5.     public abstract class Database
    6.     {
    7.         /// <summary>
    8.         /// Num of assets the database references.
    9.         /// </summary>
    10.         public int NumOfEntries { get { return mKeys.Count; } }
    11.  
    12.         /// <summary>
    13.         /// Gets an asset at a certain index.
    14.         /// </summary>
    15.         /// <param name="index">Index into asset list to look.</param>
    16.         /// <returns>Asset at the index.</returns>
    17.         abstract public DatabaseAsset GetAssetAtIndex(int index);
    18.  
    19.         /// <summary>
    20.         /// Get an asset with a certain 16 bit ID.
    21.         /// </summary>
    22.         /// <param name="assetKey16">16 bit asset ID.</param>
    23.         /// <returns>The asset matching the specified ID.</returns>
    24.         abstract public DatabaseAsset GetAsset(short assetKey16);
    25.     }
    All databases will have this data, allows for accessing data at runtime. The databases contain the references to ScriptableObject Assets that are in the project view using the same way unity does, it follows the same rules as if you were referencing a Prefab, or GameObject in a script. It is using instance ids at a base level yes, but unity maintains and updates these references for you. Well as long as you only move files using the Unity Project view interface, if you were to open the project in a File Explorer then move a ScriptableObject to a new folder, you will loose all references in a project to that ScripableObject when you update the Project, I believe. This will require a user to update every reference in every Script so that the reference pointed to the new location for the ScirptableObject.

    Its best to only move files around using the unity project view. Also using this method allows a user to create .unityPackage files and have all references intact. I also let the user know if they ever have conflicting Database Ids, which only occur when coping a database, and importing a database from a package that contains the exact same id. This is a 1 in 32000 chance, so it shouldn't be much of a worry.

    I hope this is enough information for you to get started. Let me know if you need to know more. I'm sorry for not having better documentation. I do still want to update the asset a bit more before advertising it anything but the work in progress forum.

    Thank you @hsjaaa for the questions, I'm glad to get this kind of information down for better documentation.
     
    Last edited: Aug 11, 2019
  22. hsjaaa

    hsjaaa

    Joined:
    Apr 30, 2016
    Posts:
    29
    Thanks for your reply. My concern about the serialization is serialize the reference to a Json file or something like a Player save. If use Api like JsonUtility.ToJson if there is nested reference in the SO it will be serialized as instanceID, that probably won't change in a same build but I am not sure, but it seems change from session to session.
    So maybe there is some way to serialize the reference to a ID in the database, and in loading process load the reference from database using ID?
     
  23. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    Yes I have a mistake in the code that is spitting out false logs, I am fixing it, and making it to where The plugin wont use so much time on recompile, and loading. Thanks for the input Mate!
     
  24. hsjaaa

    hsjaaa

    Joined:
    Apr 30, 2016
    Posts:
    29
    Sorry if I didn't make myself clear but you probably misunderstand me. I don't have the asset yet, just want to ask if that asset can achieve certain things, like serialize nested SO reference to a save file and load it back through the database ID saved in the file. If the save file gonna be used through serveral game build, The default instanceID seem not so reliable to be used in a save file, becase the save file is outside of the Unity's control.
     
  25. manurocker95

    manurocker95

    Joined:
    Jun 14, 2016
    Posts:
    210
    I am in the same boat as hsjaaa. I wanna save scriptableobject references or ids in the savefile so I can load them when game loading. Is that possible?
     
  26. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    If you read a few posts above I explain and show code for saving the data to an id, and retrieving it at runtime via the MainDatabaseCollection. In the case above the user is storing an id as a int for a database, and using that int value along with MainDatabaseCollection.GetDatabase(int id) to access the databases ScriptableObject at runtime in the example code.
     
  27. Andrew900460

    Andrew900460

    Joined:
    Aug 9, 2017
    Posts:
    39
    I know I asked this before a long time ago @icepick912, but you should make a discord so we can have a more convenient dialogue with you and talk about your project more productively. I really enjoy using this database, and I considered actually donating additional money to give you a reason to keep making it. If your not actually getting much just from sales. Also, I might do a shoutout to your project on our twitter (we have 443 followers right now, not much but...) to hopefully help more people see you as well if its just a matter of exposure, but I would appreciate you setting up a discord.

    Lastly, I wanted to show you something you might be interested in. Right now, to create a new database, you have to actually create a temporary scriptable object file that you use to set it up. But I found this source code somone posted on twitter that was for another asset I use called Odin Inspector (pairs nicely with your asset), and it is an editor window finds and lists all the scriptable object source files somehow, and allowed you to pick one and create it without the need of adding a [Create Asset] attribute thing. And I have a feeling there is something in that source code you can use to make it so you can allow us to pick from a list to create the desired database without needing to create a temp file.

    I will append the source file to this message. At this point in my project, I am fully utilizing your database to its greatest extent and I don't want you to stop supporting it any time soon, or for the foreseeable future. I have a database for ITEMS, BLOCKS, BIOMES, ENTITIES, ORES, and soon to be CRAFTING RECIPES. Yes I know this sounds like Minecraft but humor me here. Anyway, you're doing something good here with this unity asset, and I feel bad for not showing much support to you, and I feel like you're not getting as many sales as you might imagine. So I want to help with that in the ways that I can. But I would appreciate if you made a discord ;)
     

    Attached Files:

    icepick912 likes this.
  28. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    Well thanks Andrew! I surely can create a discord for help and such. More money is not necessary, plus you are a great supporter of my asset, thank you for that. Ill admit I have been preoccupied with other things and haven't really finished the asset to the level I wanted. I still need proper documentation, and some tutorial videos and such. Me making this asset was to see how the process of releasing anything to the public goes, as this is the first thing I have ever put a price on. I'm very happy to hear you are getting good milage from the asset. Such a regular user has plenty of feedback I am sure, and would love to hear it. Ill post a discord link when I set it up here in a moment.

    As for auto detecting scripableObjects and displaying a list of them instead of the intermediate step of creating a ScriptableObject and selecting it to create databases, I see it as very doable, and will check out the attached example. Thank you for that.

    Thank you for all the support! @Andrew900460 Sorry to be a bit absent the last few months.
     
  29. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
  30. Miguelfanclub

    Miguelfanclub

    Joined:
    Jun 14, 2015
    Posts:
    64
    You have missing scripts in your only example scene. Can you fix it?
     
  31. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    Hm I don't see any missing scripts, which version of unity are you using?
     
  32. Miguelfanclub

    Miguelfanclub

    Joined:
    Jun 14, 2015
    Posts:
    64
    2019.3
    I have just install it in the project and opened the example scene.
    Edit: The GO with the missing prefab is "RuntimeText"
     
    Last edited: Feb 13, 2020
  33. manurocker95

    manurocker95

    Joined:
    Jun 14, 2016
    Posts:
    210
    Missing scripts are usually due to UI stuff or packages if opened in lower version than the develop one.

    My question:

    Are scriptable objects saved by metadata hash? I made my own database but I wouldn't mind to buy this asset if it does
     
  34. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    ScriptableObjects are themselves just like any other asset, so yes unity serializes ScriptableObjects with an internal metadata structure. I however use a custom id that contains both the database, and asset ids that can be used to get the data from run-time, or in the editor. Refer to the above posts on how to access the data, or look at the example script "CustomEditorTest" To see how to use the ids to get the desired data.
     
  35. icepick912

    icepick912

    Joined:
    Jul 8, 2010
    Posts:
    58
    The item missing is a Text https://docs.unity3d.com/2018.3/Documentation/ScriptReference/UI.Text.html
    I suppose its no longer available after 2018.3, it is only there to show the data is loaded at run-time, the least important example script in my opinion.
     
  36. gareth_untether

    gareth_untether

    Joined:
    Jan 5, 2018
    Posts:
    69
    I'm adding a ScriptableObject to the Database with the following:

    Code (CSharp):
    1.     [SerializeField] private TestingDataBaseFile dataBase = null;
    2.     [SerializeField] private GameItem gameItem = null;
    3.  
    4.     private void Start()
    5.     {
    6.         dataBase.AddNew("Nut", gameItem);
    7.     }
    The item is added, but when I select the item in inside of the inspector while the database is selected I receive the following error:

    Code (CSharp):
    1. uvs not found for 1749
    2. UnityEngine.Debug:LogError(Object)
    3. MyLib.Shared.Database.IconAtlas:get_Item(Int32) (at D:/Unity/_AssetStoreDev/_VsProjects/ScriptableObjectDatabaseRuntime/ScriptableObjectDatabaseRuntime/Scripts/IconAtlas.cs:49)
    4. MyLib.EditorTools.DatabaseWindowEditor:DrawPreviewGUI(Rect, GUIStyle, IDatabaseFile) (at D:/Unity/_AssetStoreDev/_VsProjects/ScriptableObjectDatabaseEditor/ScriptableObjectDatabaseEditor/Scripts/Base/DatabaseWindowEditor.cs:987)
    5. MyLib.EditorTools.DatabaseInspectorBase`2:OnInteractivePreviewGUI(Rect, GUIStyle) (at D:/Unity/_AssetStoreDev/_VsProjects/ScriptableObjectDatabaseEditor/ScriptableObjectDatabaseEditor/Scripts/Base/DatabaseInspectorBase.cs:62)
    6. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
    7.  
     
  37. manurocker95

    manurocker95

    Joined:
    Jun 14, 2016
    Posts:
    210
    What are the differences between File, Asset and Class generated eg: mydbFile, mydbAsset, and mydbClass? For some reason, my dbs are in .asset but can't be find by the editor nor scanner. Any clue how to link them again? because I can use them in my script. Please, add double click for open a database in the editor window.
     
  38. gareth_untether

    gareth_untether

    Joined:
    Jan 5, 2018
    Posts:
    69
    I am finding that the database doesn't always save the database items between plays. Anyone else have this issue?
     
  39. Andrew900460

    Andrew900460

    Joined:
    Aug 9, 2017
    Posts:
    39
    Where did icepick go???
    Also, anyone who sees this, he did make a discord. https://discord.gg/pYnTpQ It looks like he's been inactive for a long time, but it would be cool if he came back. I still use this asset in my project and it works very well. But it still needs a bit of work here and there.
     
    DungDajHjep likes this.