Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

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. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    Amazing! Thanks! Just one more thing, is it possible to find the Index of a BG Entity?

    (EDIT) because I want to change the Meta but keep the Entity Index...

    After adding BG Entity to UVS Type options, now I´v found it.
     
    Last edited: Aug 18, 2021
    BansheeGz likes this.
  2. Cam_Fox

    Cam_Fox

    Joined:
    Nov 23, 2018
    Posts:
    13
    Hello, I recommend adding setup information and Addressables version requirements to your documentation at https://www.bansheegz.com/BGDatabase/Downloads/RuntimeAddressables/

    I was getting a runtime error due to unknowingly using an older version of Addressables. I tried the provided test script and was getting a success message. Troubleshooting took a couple hours before I finally found the solution on this board.

    Great asset! Loving it so far. :)


    Edit: I see the version requirement listed after all, but it's easy to miss, plus Unity defaults my package manager to an older version of Addressables. Maybe adding a troubleshooting section to the documentation would help other users.
     
  3. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hello, thank you for your support and suggestions!

    Sure, we will add a better warning, sorry for the inconvenience!
     
  4. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    Hi, I´m using 2021.1.16f1 and BG database 1.6.9, after creating a single value table, when clicking to add a row, this error happens, also, maybe this is related to another issue where my data binders are not updating when changing language.

    Any ideas?

    upload_2021-8-18_22-23-30.png
     

    Attached Files:

  5. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hi, indeed, it's a bug in the localization add-on
    It's an integrity check, which fires a false alarm under certain conditions.
    I've sent a package with a fix to you in a private message.
    Sorry for the inconvenience

    Probably, data binders should not be affected by this issue
     
    AdrianoDeRegino likes this.
  6. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    [QUOTE="Probably, data binders should not be affected by this issue[/QUOTE]

    Thanks! Happens that I was not selecting $locale in the field.
     
  7. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    Thanks for all the time you've supported my doubts and issues, this is the best support I've ever received.

    I have a feature suggestion, Is it possible to keep this "choose entity" window parameters instead of always resetting it?

    Like, keeping the filter, the current page, number of rows, window size, etc...

    upload_2021-8-19_11-26-52.png

    It would be great for repetitive tasks.
     
    BansheeGz likes this.
  8. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    We made $locale field to be auto-selected when "LOC-S" table is selected

    Great idea, thank you!
    Your feedback is very helpful to us and we appreciate it a lot!
    I've sent an updated package to you in a private message.
    You need to enable the "Save" toggle

    We are also working on adding an option to select an entity without using a popup window by simply clicking and dragging a row from the main database window to the target field
     
  9. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    Wow, wasn't expecting all that, thanks you!
    The auto locale selection is pretty handy, and glad you´ve liked the suggestion.
     
  10. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    Since you´ve appreciated my last idea, here´s another one:

    Make the dark theme background darker so the text readability is improved.
    upload_2021-8-20_10-12-49.png
     
  11. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    417
    i 2nd that :)
     
    AdrianoDeRegino likes this.
  12. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    Also, how would I proceed about that?

    Surely I´m doing something very dumb.
    upload_2021-8-20_14-39-9.png
     
  13. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Thank you, it's done (I think)

    $locale is currently a local feature for data binders unfortunately
    Please, use the BGBoltGetLocale unit from the attached package
    This unit returns currenly selected locale (which can be used as a field name)

     

    Attached Files:

    AdrianoDeRegino likes this.
  14. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    We have added an option to drag entity row to field data binder to assign an entity
    Now we are adding the same feature to every component, which has an entity selection button
     
    AdrianoDeRegino likes this.
  15. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    Thak you! all that is awesome!
     
    BansheeGz likes this.
  16. AdrianoDeRegino

    AdrianoDeRegino

    Joined:
    Aug 10, 2019
    Posts:
    87
    I´m having an issue where I select "manual" and this option keeps resetting back to "Start", if I simply select another Game Object and select it again.

    upload_2021-8-24_12-24-42.png
     
    BansheeGz likes this.
  17. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    AdrianoDeRegino likes this.
  18. Parapin

    Parapin

    Joined:
    Mar 31, 2017
    Posts:
    9
    hi, I sended an email at "support@bansheegz.com" because I wanted to ask for two problems, but for now no reply, so I will ask here, maybe I made some mistake, but here my two question, however before, I must say that is a really good tool! (ah, for importing the .xls file I'm using the "excel import/export at runtime" plug-in)

    1 - when I import a number like "0,657" the "0," is removed because its seems it accept only the "0." as correct format, like some region setting is activated.

    2 - when I export the data in the excel file, I can see that an "'" is added before the number. I think this is a correct behavior for a string cell, but not a number cell (like int, float, double). after said that, I want to know if it is possible to remove the "'" even in a string cell, because for what I do a "'" before anything it create, in my case, some visuals problems.

    thanks!
     
  19. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hi!
    Sorry, we never heard about a missing email before- probably we should ask our hosting provider about it

    The default code for converting a string value to a float value is:
    Code (CSharp):
    1. return string.IsNullOrEmpty(value) ? 0 : float.Parse(value.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture);
    As far as I understand, it uses InvariantCulture, which is based on en_US culture.
    This culture uses comma as a thousands separator (1,000,000.22)
    So 1,024 value is converted to 1024 and 0,657 is converted to 657 and this makes sense- otherwise, comma obtains different meaning
    Probably, you could use a custom string formatter to override the default implementation
    Here is a string formatter class for a float field, which acts exactly as the default implementation
    Code (CSharp):
    1. using System.Globalization;
    2. using BansheeGz.BGDatabase;
    3.  
    4. public class FloatToStringConverter : BGStringFormatter<float>
    5. {
    6.     public float FromString(string value)
    7.     {
    8.         return string.IsNullOrEmpty(value) ? 0 : float.Parse(value.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture);
    9.     }
    10.  
    11.     public string ToString(float value)
    12.     {
    13.         return value.ToString("g7", CultureInfo.InvariantCulture);
    14.     }
    15. }
    Put it into your project and modify FromString method as you like.
    If you have problems implementing the required conversion- please, let me know the requirements for this conversion
    To assign a custom string formatter class to your field- use "M" field's menu button under the configuration tab (note, this converter will work only for float fields)
    1) Int and float fields are exported as numeric values- so they should not have a leading apostrophe symbol

    2) Long and double fields are exported as string values, not numeric ones because Excel (as far as I remember) does not have enough precision for C# long and double values- some values got rounded up.
    So after you exported some value to Excel and imported it back to the database the value may change. Since round-trip conversion is the highest priority for us- we decided to export such fields as strings (and this keeps the value intact). If you know a better solution for this problem- please, let me know.

    Also, unfortunately, it can not be customized with a string formatter, I mentioned earlier- cause it deals with string values only, but we could extend it with another interface for Excel specifically and provide an option to define value type (string or numeric) by giving access to NPOI Cell class (which encapsulate an Excel cell). With the new interface, you can decide if you want to export value as a string or as a number- for example for a long value you can check- if the value is out-of-range it can be exported as a string value and if it's within valid range- it can be exported as a numeric value. Please, let me know if you are interested.

    3) I'm not sure, I think the main reason why the string field can get a leading apostrophe symbol- in case the value can be converted to a number (the same reason why long and double fields get a leading apostrophe symbol).
    A leading apostrophe symbol is added automatically (probably by NPOI, but I'm not sure) to mark the value as a string value, not a numeric value- if you set a string value, which can be converted to a number
    We do not add this symbol- it's added automatically.
     
  20. Parapin

    Parapin

    Joined:
    Mar 31, 2017
    Posts:
    9
    no I'm sorry, I think it was a problem with thunderbird, it says it was sended, but I had some connection problems.

    so, then I tried to change the code with this:
    Code (CSharp):
    1.  
    2.  
    3.      return string.IsNullOrEmpty(value) ? 0 : float.Parse(value.Trim(), NumberStyles.Any, CultureInfo.CurrentCulture);
    4.  
    5.  
    with the CultureInfo.CurrentCulture and then I loaded the script like your example, but with no success, surely I made some mistakes.
    yes, I think it's a good idea to export fields as strings to resolve the problem, exactly, for the culture problem I imported the data as strings, at the end I'm importing time data so, like "14:00" it becomes "0,583333333", so I'm ok to use string as type. for now, I don't think I need a new interfaces, thank.
    uhmmm, I have all the importer updated, "excel integration for editor" at 1.7 and "excel file monitor for runtime" at 1.1, so if I'm exporting from excel integration, the int and float are without the apostrophe, and the string with it
    https://ibb.co/ZLFL7xt
    and this with runtime, int, float, even the bool, string with apostrophe
    I'm doing something wrong?
    so, If I'm not wrong its seems that, for a string value a ' is added in automatic from NPOI? so there are no possibility to remove it? I'm out of luck? :)

    uhmm, I have tried something new, I exported with the normal editor export plugin a 0.13 float and in the file excel it was good but, when exported with the runtime editor the float become 0.129999995

    thanks again!

    ps: exporting a word as a string like "house" with runtime, didn't add the ', its seems only number are affected...

    pss. maybe I found something, when I'm importing a number as a string, with runtime, Iike "0,12" with the comma, the exporting with the editor it will add the ' but if the number imported as a string it was "0.12" no apostrophe, so it's a problem with the culture info, I want to say.
     
    Last edited: Aug 26, 2021
  21. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    1) Please, install the latest Excel runtime plugin (v 1.2) https://www.bansheegz.com/BGDatabase/Downloads/RuntimeExcelMonitor/
    I was not aware it was not published, sorry for the inconvenience
    It requires the latest BGDatabase release (v. 1.6.10)

    2) Another option is to use some culture explicitly instead of CurrentCulture
    For example, the German one should work ok probably (1.000.000,22)
    Code (CSharp):
    1. using System.Globalization;
    2. using BansheeGz.BGDatabase;
    3.  
    4. public class FloatToStringConverter : BGStringFormatter<float>
    5. {
    6.     private readonly CultureInfo cultureInfo = CultureInfo.GetCultureInfo("de-DE");
    7.  
    8.     public float FromString(string value)
    9.     {
    10.         return string.IsNullOrEmpty(value) ? 0 : float.Parse(value.Trim(), NumberStyles.Any, cultureInfo);
    11.     }
    12.  
    13.     public string ToString(float value)
    14.     {
    15.         return value.ToString("g7", cultureInfo);
    16.     }
    17. }
    18.  
    It turned out that we already had support for such an interface for export, so we just added the same interface for import, so both interfaces now can be used


    The latest package should not have the errors, you mentioned.
    Please, try it and If something does not work as expected- please, let me know

    Yes, the apostrophe is added to the string value only if the value is convertible to a number.
    We do not know who adds this- NPOI or Excel, but it seems to be a standard way for Excel to mark the value as a string value, not a number value.

    The only way we know to get rid of this apostrophe is to export data as a number, not as a string
    For example, this custom converter for string field does it (but I'm not sure about round-trip conversion in this case):
    Code (CSharp):
    1. using System.Globalization;
    2. using BansheeGz.BGDatabase;
    3. using NPOI.SS.UserModel;
    4.  
    5. public class CustomStringFormatter : BGStringFormatter<string>, BGExcelCellWriteProcessorRT
    6. {
    7.     //change culture if needed
    8.     private readonly CultureInfo culture = CultureInfo.InvariantCulture;
    9.  
    10.     public string FromString(string value)
    11.     {
    12.         return value;
    13.     }
    14.  
    15.     public string ToString(string value)
    16.     {
    17.         return value;
    18.     }
    19.  
    20.     public void OnWrite(ICell cell, BGField field, BGEntity entity)
    21.     {
    22.         var value = field.GetValue(entity.Index) as string;
    23.         if (string.IsNullOrEmpty(value)) cell.SetCellValue((string) null);
    24.         else
    25.         {
    26.             //if string value is parseable as a number- use number value instead of string value
    27.             if (int.TryParse(value, NumberStyles.Any, culture, out var intValue)) cell.SetCellValue(intValue);
    28.             else if (float.TryParse(value, NumberStyles.Any, culture, out var floatValue)) cell.SetCellValue(floatValue);
    29.             //otherwise use string value
    30.             else cell.SetCellValue(value);
    31.         }
    32.     }
    33. }
     
  22. Parapin

    Parapin

    Joined:
    Mar 31, 2017
    Posts:
    9
    yes, changing in German worked! thanks!
    yes, its seems to working correctly.
    tried and initially didn't work correctly (different number), then I changed the culture and I made some try... it's work! I will test more to see if all is correct. well... what can I say? thanks again!
     
    BansheeGz likes this.
  23. bconstantin

    bconstantin

    Joined:
    Feb 4, 2019
    Posts:
    15
    Hello, there is a BIG bug on address memory management.

    Seems addressable are kept in memory after unloading the database. See attachment.
    I access the value so the sprite load, and after this I release it, and in memory it is still here.

    What is expected for me: Loading a partition load the sprite (and not load it on demand), unloading the partition unload it from Addressables.


    Edit: Ok found, each time you access the value it load it on Addressable. Which is totally unexpected. If it's already loaded, donc try to load it again from Addressables;
     

    Attached Files:

    Last edited: Oct 1, 2021
  24. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hello, sorry, the current implementation of partitioning addon never unload any asset under any circumstances.
    We updated our docs and mentioned it explicitly

    Here is the detailed explanation why:
    If you load a partition- it does not also mean that referenced assets are also loaded.
    Assets are loaded on-demand when you read the asset field's value.
    So if you load a partition and immediately unload it- no assets will be loaded at all.
    And there is no reliable method for us to determine- if the particular asset was loaded and if loaded- how many times.
    This is essential information we need to know to unload the asset.
    Internally addressables keeps the reference counter- how many times the asset was loaded.
    For example, if you loaded the asset twice- you need to call Addressables.Release method twice- otherwise, the asset will not be unloaded.
    On your screenshot there are 2 images that are loaded twice- so you need to call the release method twice for these assets
    Also, the same asset can be loaded externally, for example as part of the scene loading.

    The bottom line is- since we can not determine
    1) was the asset loaded
    2) if loaded -who many times
    3) is this asset used anywhere else, apart from the database
    - we can not implement assets releasing properly.

    If you know that all your assets, referenced from partition, was loaded exactly 1 time- you can try to use the following code to release the memory
    Please, note:
    1) if some asset was not loaded at all an exception will be printed to the console (harmless)
    2) if some asset was loaded more than 1 time- it will not be unloaded, cause the ref counter will not be equal to zero
    3) it looks like we need to call Resources.UnloadUnusedAssets(); after decreasing asset counter to zero, otherwise the memory will not be released until ref counter for asset bundle reaches zero, according to this article (https://docs.unity3d.com/Packages/com.unity.addressables@1.16/manual/MemoryManagement.html)

    Code (CSharp):
    1. using System;
    2. using BansheeGz.BGDatabase;
    3. using UnityEngine;
    4. using UnityEngine.AddressableAssets;
    5.  
    6. using Object = UnityEngine.Object;
    7.  
    8. public class Test : MonoBehaviour
    9. {
    10.      private void UnloadPartition(int partition)
    11.     {
    12.         var addonPartition = BGRepo.I.Addons.Get<BGAddonPartition>();
    13.  
    14.         //unload assets
    15.         //iterate over partitioned metas
    16.         BGRepo.I.ForEachMeta(meta =>
    17.         {
    18.             var partitionField = meta.GetField(BGAddonPartition.PartitionFieldName);
    19.             Predicate<int> partitionFilter;
    20.             var partitionOneBased = partition + 1;
    21.             switch (partitionField)
    22.             {
    23.                 case BGFieldByte fieldByte:
    24.                     partitionFilter = index => fieldByte[index] == partitionOneBased;
    25.                     break;
    26.                 case BGFieldShort fieldShort:
    27.                     partitionFilter = index => fieldShort[index] == partitionOneBased;
    28.                     break;
    29.                 case BGFieldInt fieldInt:
    30.                     partitionFilter = index => fieldInt[index] == partitionOneBased;
    31.                     break;
    32.                 case BGFieldRelationSingle fieldRelation:
    33.                 {
    34.                     var partitionEntity = fieldRelation.To[partition];
    35.                     partitionFilter = index => Equals(fieldRelation[index], partitionEntity);
    36.                     break;
    37.                 }
    38.                 default:
    39.                     throw new Exception($"Unsupported partition field type {partitionField.GetType().FullName}");
    40.             }
    41.  
    42.  
    43.             //iterate over all addressables fields
    44.             meta.ForEachField(field =>
    45.             {
    46.                 //iterate over all rows
    47.                 meta.ForEachEntity(entity =>
    48.                 {
    49.                     //skip if a partition is not equal to the partition being unloaded
    50.                     if (!partitionFilter(entity.Index)) return;
    51.  
    52.                     var address = ((BGAddressablesAssetI)field).GetAddressablesAddress(entity.Index);
    53.  
    54.                     //skip if value is not set
    55.                     if (string.IsNullOrEmpty(address)) return;
    56.  
    57.                     //release asset
    58.                     switch (field)
    59.                     {
    60.                         case BGFieldUnityAudioClip _:
    61.                             Release<AudioClip>(address);
    62.                             break;
    63.                         case BGFieldUnityFont _:
    64.                             Release<Font>(address);
    65.                             break;
    66.                         case BGFieldUnityMaterial _:
    67.                             Release<Material>(address);
    68.                             break;
    69.                         case BGFieldUnityObject _:
    70.                             Release<Object>(address);
    71.                             break;
    72.                         case BGFieldUnityPrefab _:
    73.                             Release<GameObject>(address);
    74.                             break;
    75.                         case BGFieldUnityScriptableObject _:
    76.                             Release<ScriptableObject>(address);
    77.                             break;
    78.                         case BGFieldUnitySprite _:
    79.                             Release<Sprite>(address);
    80.                             break;
    81.                         case BGFieldUnityTexture _:
    82.                             Release<Texture>(address);
    83.                             break;
    84.                         case BGFieldUnityTexture2d _:
    85.                             Release<Texture2D>(address);
    86.                             break;
    87.                         default:
    88.                             throw new ArgumentOutOfRangeException(nameof(field));
    89.                     }
    90.                 });
    91.             }, field => field is BGAddressablesAssetI && field is BGAssetLoaderA.WithLoaderI && ((BGAssetLoaderA.WithLoaderI)field).AssetLoader is BGAssetLoaderAddressables);
    92.         }, meta => meta.HasField(BGAddonPartition.PartitionFieldName));
    93.  
    94.      
    95.         //calling this method may have undesired consequences
    96.         Resources.UnloadUnusedAssets();
    97.  
    98.         //unload database data
    99.         addonPartition.Unload(partition);
    100.     }
    101.  
    102.     private void Release<T>(string address)
    103.     {
    104.         //load the asset once and unload it twice
    105.         var asset = Addressables.LoadAssetAsync<T>(address).WaitForCompletion();
    106.         if (asset == null) return;
    107.         Addressables.Release(asset);
    108.         Addressables.Release(asset);
    109.  
    110.     }
    111. }
    Addressables already has an internal cache for loaded assets- what could be the reason for adding another cache on top of the addressable one?
     
  25. bconstantin

    bconstantin

    Joined:
    Feb 4, 2019
    Posts:
    15
    Yeah I understand, It was very confusing at first, but it's ok now.
    It's just that you have to keep your reference elsewhere than just by accessing the field, and during my test I just wnated to release the resources without my own cache. Which is actually not possible.

    Maybe a generated function Like field.Unload would be very cool ?

    Because we can't access variable without trying to load it actually, and it's the main problem ?
     
  26. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    I think the main problem is that we can not figure out how many times database assets was loaded and how many times we should call Addressables.Release to unload them.
    Another solution (probably a bad one) is to use your own counter for each asset
    Each time asset is loaded- the counter is increased by 1
    Database byte/short/int field can be used as a counter
    When you need to unload the asset- iterate over rows and if the counter > 0, call the method below and pass the counter and the field as a parameters
    To get a reference to a field use {YourGeneratedClass}._{Field_Name} property
    The extension method for BGEntity class can be used instead of generated method, cause it does not take advantage of the database structure.
    This method is based on the method I posted earlier
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using BansheeGz.BGDatabase;
    4. using UnityEngine;
    5. using UnityEngine.AddressableAssets;
    6. using Object = UnityEngine.Object;
    7.  
    8. public static class BGEntityAddressablesExtentions
    9. {
    10.     //unload unity assets values
    11.     public static void UnloadAddressablesAssets(this BGEntity entity, int unloadCounter = 1, params BGAddressablesAssetI[] fields)
    12.     {
    13.         // get Addressables fields
    14.         var fieldsToUnload = new List<BGAddressablesAssetI>();
    15.         if (fields != null && fields.Length > 0) fieldsToUnload.AddRange(fields);
    16.         else
    17.         {
    18.             entity.Meta.ForEachField(
    19.                 field => fieldsToUnload.Add((BGAddressablesAssetI)field),
    20.                 field => field is BGAddressablesAssetI && field is BGAssetLoaderA.WithLoaderI && ((BGAssetLoaderA.WithLoaderI)field).AssetLoader is BGAssetLoaderAddressables
    21.             );
    22.         }
    23.  
    24.         if (fieldsToUnload.Count == 0) return;
    25.  
    26.         foreach (var field in fieldsToUnload)
    27.         {
    28.             var address = field.GetAddressablesAddress(entity.Index);
    29.             if (string.IsNullOrEmpty(address)) continue;
    30.        
    31.             //release asset
    32.             switch (field)
    33.             {
    34.                 case BGFieldUnityAudioClip _:
    35.                     Release<AudioClip>(address, unloadCounter);
    36.                     break;
    37.                 case BGFieldUnityFont _:
    38.                     Release<Font>(address, unloadCounter);
    39.                     break;
    40.                 case BGFieldUnityMaterial _:
    41.                     Release<Material>(address, unloadCounter);
    42.                     break;
    43.                 case BGFieldUnityObject _:
    44.                     Release<Object>(address, unloadCounter);
    45.                     break;
    46.                 case BGFieldUnityPrefab _:
    47.                     Release<GameObject>(address, unloadCounter);
    48.                     break;
    49.                 case BGFieldUnityScriptableObject _:
    50.                     Release<ScriptableObject>(address, unloadCounter);
    51.                     break;
    52.                 case BGFieldUnitySprite _:
    53.                     Release<Sprite>(address, unloadCounter);
    54.                     break;
    55.                 case BGFieldUnityTexture _:
    56.                     Release<Texture>(address, unloadCounter);
    57.                     break;
    58.                 case BGFieldUnityTexture2d _:
    59.                     Release<Texture2D>(address, unloadCounter);
    60.                     break;
    61.                 default:
    62.                     throw new ArgumentOutOfRangeException(nameof(field));
    63.             }
    64.         }
    65.     }
    66.     private static void Release<T>(string address, int unloadCounter)
    67.     {
    68.         //load the asset once and unload it twice
    69.         var asset = Addressables.LoadAssetAsync<T>(address).WaitForCompletion();
    70.         if (asset == null) return;
    71.         for (var i = 0; i <= unloadCounter; i++) Addressables.Release(asset);
    72.     }
    73. }
    I wish we could come up with a better solution someday
     
    Last edited: Oct 4, 2021
    bconstantin likes this.
  27. Philkrom

    Philkrom

    Joined:
    Dec 26, 2015
    Posts:
    87
    Hello
    can you please tell me where I can find documentation about the Incoming Relations tab in the configuration of a BG DB ? I would like to fill a field with an information trom another table but I don't understand how this can be done
    Best regards, Phil
     
  28. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hello,

    "Incoming relations" table shows all relational fields (from the whole database), which point to the current meta (table)

    For example, let's say you have the "Items" table and the "ItemType" table.
    "Items" table has "itemType" relational field, which points to "ItemType" table row (as shown on the screenshot below)
    The relational fields (relations) are created just like any other field- under "Configuration" tab
    When the "Items" table is selected, the relational field is shown among other fields
    When the "ItemType" table is selected, this relation from the "Item" table is shown under "Incoming relations"
    The "Incoming relations" table shows the id and name of the relation("itemType") and the meta (table), the relation belongs to, in our case, it's the "Items" table
    If you add another relational field, pointing to "ItemType" table row (no matter which table owns it), it will also be shown under the "Incoming relations" table

    Please, let me know if you have any questions
     
  29. Philkrom

    Philkrom

    Joined:
    Dec 26, 2015
    Posts:
    87
    Thanks a lot, very clear, as usual ! I didn't find any information about the relationSingle type in the Help Topics ? Maybe I am wrong ?

    I have another question.
    I am using your asset to collect in-game information : for instance, if somebody clicks an object, a new line is created with an id (corresponding to the user) + the clicked object. It works fine.
    Now I would like to let an external user see this information in realtime.
    I wanted to do this with a synced GoogleSheet, but as I can read there is no way to write in a Google sheet directly from the app, so I am looking for another way.
    Is it possible to write in a disant DB located in a server, that could be acceded with another app ? Or any other idea that could be simple to implement, as I am not a C# coder, only a PlayMaker user.
    Best regards !
    Philippe
     
  30. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    417
    Is there a new latest version that you can PM me again with all the changes or should I stick with the store version? You had sent me a bunch of revisions before in PM
     
  31. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hello, Philippe, you are right- we will add information about relational fields soon to this page (https://www.bansheegz.com/BGDatabase/SupportedFields/).
    Basically, the relationSingle field stores a reference to a database row, similar to a single column nullable foreign key (https://www.educative.io/blog/what-is-foreign-key-database)
    "RelatedMeta" parameter defines the table, the relation references (parent table)
    We will also add 2 new relational fields with multiple parent tables to the next update (version 1.7.1).

    1) If all you want to do - is to add new rows to the GoogleSheets spreadsheet- you could use GoogleForm->GoogleSheet integration as described here https://www.bansheegz.com/BGDatabase/ExportImport/#why (at the bottom of the page)
    There is also a link to a mini-guide I posted on this forum.
    Briefly, you need to make an HTTP POST request to GoogleForm URL and pass the required parameters to append a row to a spreadsheet.
    WebRequest Playmaker action should support HTTP POST requests (https://hutonggames.com/playmakerforum/index.php?topic=23329.0)

    2) If adding rows is not enough and you need additional operations (like modifying, deleting, querying etc.)- probably another solution is needed
    Unfortunately, I can not recommend any product/service, cause we do not have enough knowledge in this domain
    Playfab seems to have a Playmaker plugin on Asset Store, but I don't know if Playfab supports the features you need
     
    Last edited: Dec 12, 2021
  32. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    We will release the 1.7.1 version soon, please, upgrade when it's out.
    Also, the runtime editor plugin (https://www.bansheegz.com/BGDatabase/Downloads/RuntimeEditor/) will be upgraded to version 1.3 after this release- please, install it as well
    There will be a notification icon next to the "Plugins" label as soon as it's out
     
    zKici likes this.
  33. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hello,
    The initial 1.7.1 release had a bug with a code generator, which comes up if MonoBehaviour generated classes and new Addressables plugin (v.1.3) are used
    After code generation, the following error is printed to the console: "error CS0103: The name 'Id' does not exist in the current context"

    If you encounter this bug- please, update the packages from Asset Store
    Sorry about that :oops:
     
  34. Philkrom

    Philkrom

    Joined:
    Dec 26, 2015
    Posts:
    87
    Hello
    If I create in my DB a listVector2 or listVector3 field, I can see them in the Fields list. But once I have generated the PlayMaker actions, as usual, these fields don't appear in the SetByName or SetByIndex actions? I don't have this issue with a listString or a listColor which are present in the action and can be modified with PlayMaker.
    Best regards
    Phil
     
  35. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hello,
    Indeed, these fields were missing for some reason
    I've sent you an updated package in a private message
     
    Philkrom likes this.
  36. Philkrom

    Philkrom

    Joined:
    Dec 26, 2015
    Posts:
    87
    Thanks, but now I get 12 errors when I generate the PM actions : (I mean 4 times the 3 following errors)

    Assets\PlayMaker Custom Actions\BGD\BansheeActions.cs(6372,11): error CS1519: Invalid token '(' in class, struct, or interface member declaration
    Assets\PlayMaker Custom Actions\BGD\BansheeActions.cs(6372,26): error CS8124: Tuple must contain at least two elements.
    Assets\PlayMaker Custom Actions\BGD\BansheeActions.cs(6372,27): error CS1519: Invalid token ';' in class, struct, or interface member declaration

    And I still have these errors even :
    - if I remove the V2list Field in the DB and regenerate the actions
    - if I remove the BansheeActions.cs script and regenerate the actions.

    I tried to rollback to the last version, but it seems to me that the last version is buggy too ?

    Best regards
     
  37. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hello, Phil

    We just released version 1.7.2 on Asset Store earlier today- could you please upgrade and let me know if there are any issues with the 1.7.2 version?

    Sorry for the inconvenience
     
  38. LuiBroDood

    LuiBroDood

    Joined:
    Mar 13, 2019
    Posts:
    62
    i dont understand this.. ? CodeGen is failing? how do i fix it?
    thanks

    it does this error for all the CarPart

    Error :


    Database:


    Code:


    trying to set up Inventory system thing:
    DBCarPart has Part_Tool - manyTablesRelationSingle
     
    BansheeGz likes this.
  39. LuiBroDood

    LuiBroDood

    Joined:
    Mar 13, 2019
    Posts:
    62
    hmm i guess the enum are redundant lol, so i deleted them, but hmm enums dont work in a nesting?
     
  40. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Yes, I confirm, CodeGen addon generates the wrong result type for common enum fields
    We are working on the fix
     
    LuiBroDood likes this.
  41. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    I've sent you a package with a fix in a private message.
    Sorry for the inconvenience
     
  42. losemarins

    losemarins

    Joined:
    May 16, 2020
    Posts:
    1
    Hi.
    There was a problem using this system.

    When I create the field myself, I can add Enum Type.
    However, Enum Type cannot be added when importing from Google Sheet.

    I couldn't even modify the type of each field in the Configuration tab after import.

    What should I do?
     
  43. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    Hi!

    I've sent an upgraded package to you by email

    1) To select "enum" type in Data Extraction Wizard, select "Show all fields" menu item, then select "enum" type and enter full enum type name (as shown on the screenshots below)



    2) To change the existing field type to enum type, select "Change field type" menu item in the "M" field's menu, select enum type, enter full enum type name and click on the "Change field type" button (as shown on the screenshots below)




    Please, let me know if you have any questions
     
  44. moroc

    moroc

    Joined:
    Jan 20, 2014
    Posts:
    12
    Is it possible to callback method when certain record changed after load with addon?
    BGAddonSaveLoad.AfterLoadReciever and Listener on mono generated component don't work.
     
  45. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    We've added field values listeners to saveload addon
    I've sent you an upgraded package in a private message UPD: I can not PM you for some reason, could you please, send me your email address- so I could send you an upgraded package?

    There are 2 options:
    1) Entity listener (it listens to any field value change for the provided entity)
    2) Cell listener (it listens to the provided field+entity value change)

    Example usage is under the spoiler tag below.
    Code (CSharp):
    1. using BansheeGz.BGDatabase;
    2. using UnityEngine;
    3.  
    4. public class Temp : MonoBehaviour
    5. {
    6.     private void Awake()
    7.     {
    8.         //get addon
    9.         var addon = BGRepo.I.Addons.Get<BGAddonSaveLoad>();
    10.         //add entity listener
    11.         var entityPointer = new BGEntityPointer(DB_Weapon.MetaDefault.Id,DB_Weapon.GetEntity(0).Id);
    12.         addon.AddEntityListener(entityPointer, EntityChanged);
    13.         //add cell listener
    14.         var cellPointer = new BGCellPointer(DB_Weapon.MetaDefault.Id,DB_Weapon._damage.Id, DB_Weapon.GetEntity(0).Id);
    15.         addon.AddCellListener(cellPointer, CellChanged);
    16.      
    17.         //simulate values changing
    18.         var content = addon.Save();
    19.         DB_Weapon.GetEntity(0).name = "Updated name";
    20.         DB_Weapon.GetEntity(0).damage = 99;
    21.         addon.Load(content);
    22.  
    23.         //remove listeners (after loading addon reference has changed)
    24.         addon = BGRepo.I.Addons.Get<BGAddonSaveLoad>();
    25.         addon.RemoveEntityListener(entityPointer, EntityChanged);
    26.         addon.RemoveCellListener(cellPointer, CellChanged);
    27.     }
    28.     private void EntityChanged(object sender, BGSaveLoadEventArgsEntityChanged e)
    29.     {
    30.         print("ENTITY CHANGED: " + e.ToString());
    31.     }
    32.     private void CellChanged(object sender, BGSaveLoadEventArgsCellChanged e)
    33.     {
    34.         print("CELL CHANGED: " + e.ToString());
    35.     }
    36. }

    The reason why these listeners were missing- is cause we assume, that after loading the database- the Unity scene is also loaded- so all initialization code, located in Start/Awake methods are getting called- so the game state is rebuilt from scratch and there is no need to listen to particular rows changes.
    But if your process is different- please, use the added listeners
    We could add adding/deleting rows listeners as well if it's needed
     

    Attached Files:

    Last edited: Feb 20, 2022
  46. moroc

    moroc

    Joined:
    Jan 20, 2014
    Posts:
    12
    Thank you. Great asset, fast super fast support.
     
    BansheeGz likes this.
  47. moroc

    moroc

    Joined:
    Jan 20, 2014
    Posts:
    12
    Can you provide examples how work with objectreference type?
    In instruction meant that I need to add component BGWithId, but in editor I found only component Id wich compatible with ObjectReference type.
    But I can't use it in script to init field. And how can I get object in scene by this reference?
    upload_2022-2-23_14-23-54.png
     
  48. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    1) object reference field is used to reference and find loaded GameObject(s) in runtime.
    The C# component class is BGWIthId and the component's name under the components menu is "BansheeGz/Id" (we updated our documentation)
    If you drag GameObject to object reference field cell- this component will be added automatically (if it's not already added)
    Once the value is assigned- you can read the field value to get the reference to GameObject in runtime.

    Please, note, if the referenced GameObject is unloaded - the field returns null

    2) There are 2 reasons why this component is required:
    2.1) To provide unique, persistent ID. Unity Object has GetInstanceId method, but instance Id is not persistent and can not be used as a persistent ID
    2.2) To put GameObject in the cache for fast retrieval
    The alternative is using Object.FindObjectsOfType but it's so slow so it makes the field unusable
    The original idea comes from this example project, provided by Unity https://github.com/Unity-Technologies/guid-based-reference

    3) There is also an object list reference field, which returns the list of GameObjects with the same IDs

    4) I've uploaded an example project here, which demonstrate how to use these fields (object reference and object list reference): https://drive.google.com/file/d/1XP55BoqMWNeg7nVUk9JtoRtu8HvYLHg7/view?usp=sharing
    Import BGDatabase package after opening this project
    Run Assets\Scenes\SampleScene.unity scene
    The C# script: Assets\Scripts\Test.cs

    Please, let me know if you have any questions
     
  49. moroc

    moroc

    Joined:
    Jan 20, 2014
    Posts:
    12
    Why doesn't it work in the editor?
    C_Pictures.GetEntity(6).F_ObjectRef; in editor raises null, in runtime ok
     
  50. BansheeGz

    BansheeGz

    Joined:
    Dec 17, 2016
    Posts:
    317
    We changed the field implementation to work in Unity Editor assembly without entering play mode.
    I've sent you an upgraded package by email