Search Unity

  1. Unity 2019.4 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  3. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

BG Database (inMemory database | Excel/Google Sheets syncing | CodeGen | Save/Load support)

Discussion in 'Assets and Asset Store' started by BansheeGz, May 3, 2018.

  1. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    146
    Hello, you want to include database file to your addressables package?
    BGDatabase supports loading from any location with a custom loader (including addressables), but I'm not sure about localization plug-in.
    Let me check it and if it does not- we will add such a feature.
    I will send you an example with a guide as soon as it's ready

    EDIT: an example project for loading database files from Addressables system with localization addon enabled can be downloaded from here https://www.bansheegz.com/BGDatabase/Downloads/ExampleLocalization/#customLoader
     
    Last edited: Jun 18, 2020
    mike6502 likes this.
  2. VikasYadav

    VikasYadav

    Joined:
    Jul 13, 2019
    Posts:
    1
    Hey ! BansheeGz , Nice Asset .
    But i need your Help.
    To Code Example , I only can access the BgDatabase data., but how can i fill the Database to my excel data.
    Or i need to fill the whole excel data manually in Database and then i have to access .
    Can you Please Let me Know how can i store My excel data to Database .
    Thankyou in Advance !
     
  3. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    146
    Hi!
    I wrote a little tutorial on how to import data from Excel file below (under spoiler tag)
    Additional information is available here:
    1. https://www.bansheegz.com/BGDatabase/ThirdParty/Excel/
    2. https://www.bansheegz.com/BGDatabase/ExportImport/
    Please, let me know if you have any questions!

    1) Backup your excel file just in case.
    2) Select "DataSources" and create "Excel" data source. Set path to your xls file location

    3) Select "Export/Import" and create "Excel" job, set data source to your Excel data source and mark the tables you want to import data for. You can do it by clicking on the "Create custom settings" next to the table name and toggling on "Add missing"/ "Remove Orphaned"/"Update matching" toggles.
    If you already have some data in the table you want to import, uncheck "Remove Orphaned" toggle

    4) Open your xls file. We use a naming convention to map the data for import/export.
    Excel sheet should have the same name as your database table and the first row should have field names (case sensitive). You can skip(ignore) "name" field.
    You need to repeat this step for every table you want to import.

    5) [Optional] If you want to keep the links between Excel rows and database rows, so you could update data either in Excel or database and import/export it multiple times, add "_id" column (without quotes) to your Excel file.
    Ignore this step if you want to import data only once

    6) Save and close your Excel file, save your database, switch to "Export/Import", chose your Excel job and click on the "Import" button
    After importing switch to "Log" tab and search for messages, highlighted in red. If your data has a wrong format, which can not be parsed, you'll get a warning message. Make sure you do not have such messages

    7) Switch to "Database" tab and review imported data. If everything is ok, you can save the database. Otherwise, click on the "Reload" button to revert the changes and try importing again
     
  4. mike6502

    mike6502

    Joined:
    Oct 5, 2016
    Posts:
    4
    I am migrating assets from the Resources folder to Addressables using the BGDatabase Addressables addon. It works fine, but I feel like I might be over-complicating things.

    Previously, via code generation, BGDatabase would handle the Resource.Load action for an asset synchronously.

    Code (CSharp):
    1. var sprite = GameDB.MyItems.GetEntity(itemName).itemSprite;
    Now, with Addressables, I need an extra line to get the Addressable address, and then do the addressables load process asychronously.

    Code (CSharp):
    1. var entity = GameDB.MyItems.GetEntity(itemName);
    2. var address = GameDB.MyItems._itemSprite.GetAddressablesAddress(entity.Index);
    3.  
    4. Addressables.LoadAssetAsync<Sprite>(address).Completed += op => {
    5.   if (op.Status == AsyncOperationStatus.Succeeded) {
    6.     var sprite = op.Result;
    7.   }
    8. };
    That's a lot more code than before. Is there a simpler approach?
     
  5. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    You could simply preload the asset at the beginning of the game loading time. There is an example script included in the package.
     
  6. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    146
    @mike6502
    @castor76

    Yes, preloading assets could be another alternative, but it has one big drawback- it adds additional code/complexity, I still believe that using asynchronous Addressables API without preloading is a more robust way to load assets.

    Here is another option- we have added additional methods for asset fields with Addressables loader (Load{FieldName}Async)
    They still load assets asynchronously, but they hide Addressables boilerplate code and also no need to set asset type.
    Example: Code generator generates the following method for "itemSprite" Sprite field:
    Code (CSharp):
    1.  
    2. public void LoaditemSpriteAsync(Action<UnityEngine.Sprite> completedCallback)
    3. {
    4.    var address = _itemSprite.GetAddressablesAddress(Index);
    5.    if(string.IsNullOrEmpty(address)) return;
    6.    Addressables.LoadAssetAsync<UnityEngine.Sprite>(address).Completed += op => {
    7.        if (op.Status == AsyncOperationStatus.Succeeded) completedCallback(op.Result);
    8.    };
    9. }
    10.  
    and it can be used like this:
    Code (CSharp):
    1.        
    2. MyItems.GetEntity(0).LoaditemSpriteAsync(sprite =>
    3. {
    4.    
    5. });
    6.  
    mike6502, I sent you a beta package in a private message just in case you might be interested.

    Also, if you want to customize this method, you can add your own methods to generated classes.
    Since all generated classes are partial, you can create your own class with the same name and add additional methods to it.
    Let's say you want to throw an exception in case a value is not set.
    You can add the following method:

    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine.AddressableAssets;
    4. using UnityEngine.ResourceManagement.AsyncOperations;
    5.  
    6. namespace GameDB
    7. {
    8.     public partial class MyItems
    9.     {
    10.         public void LoadItemSprite(Action<UnityEngine.Sprite> completedCallback)
    11.         {
    12.             var address = _itemSprite.GetAddressablesAddress(Index);
    13.             if (string.IsNullOrEmpty(address))
    14.                 throw new Exception("Value is not set. Entity=" + Name);
    15.  
    16.             Addressables.LoadAssetAsync<UnityEngine.Sprite>(address).Completed +=
    17.                 op =>
    18.                 {
    19.                     if (op.Status == AsyncOperationStatus.Succeeded)
    20.                         completedCallback(op.Result);
    21.                 };
    22.         }
    23.     }
    24. }
    25.  
     
  7. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    While I do agree with above, I found that while I use database, say for example item. Async operation was not an option.
    You really don't want to wait for it to load and it also adds complexity during actually using it. I did not want any middle man hanging around when all I wanted is to get the value or an asset from database.

    Preloading does indeed adds complexity in the beginning of the game loading time, but that's just one place you deal with. And then rest of the game related code is free from all this Async business.

    Choice is there so it's always a good thing!
     
  8. mike6502

    mike6502

    Joined:
    Oct 5, 2016
    Posts:
    4
    Thanks @BansheeGz, the beta package with updated code gen works great for me. My code is now much simpler.

    I also didn't realize that the generated classes were partial - that's great to know.

    @castor76, you're right, preloading will work for some of my assets. The use case I mentioned above is with an in-game catalog where players scroll and choose from hundreds of items. Preloading is not optimal there, and is one of many reasons why I am migrating away from Resources.

    Thanks!
     
    BansheeGz likes this.
  9. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    146
    @castor76
    @mike6502

    The main concern about preloading technique is that it relies on internal addressables cache, which returns an asset synchronously after this asset was loaded for the first time
    I doubt that this behaviour is part of the public addressables interface.
    We do use standard LoadAssetAsync method, but the fact that asset is returned immediately could be some side effect.
    It's really hard to predict how this cache acts in all possible situations.
    So I do believe that using async addressables API is a safer option.
     
  10. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    1,725
    I am all using preloading in my game so I will be watching out for any problems in the future.
     
    BansheeGz likes this.
unityunity