Search Unity

[RELEASED]Visual Item Database - Game Items Management and Editing Tool

Discussion in 'Assets and Asset Store' started by bloeys, Apr 13, 2016.

  1. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    Awesome!
    Aside from the fact that you don't need to cast to int since itemID is already an integer, your code looks good :D
    Have fun using the VID and contact me here or on my email and I will be happy to help ;)
     
  2. validname1

    validname1

    Joined:
    Feb 1, 2018
    Posts:
    23
    Hi, I'm having a hard time getting this EnumMask implementation working on the Editor Display. I keep getting this error:
    Code (CSharp):
    1. ArgumentException: Field flags defined on type ItemSystem.ActorDefinition is not a field on the target object which is of type ItemSystem.Database.VIDItemListsV32.
    2. Parameter name: obj
    3. System.Reflection.MonoField.GetValue (System.Object obj) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoField.cs:110)
    4. EnumMaskPropertyDrawer.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at Assets/Scripts/Shared/EnumMaskPropertyDrawer.cs:31)
    5. UnityEditor.PropertyDrawer.OnGUISafe (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at C:/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyDrawer.cs:22)
    6. UnityEditor.PropertyHandler.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren, Rect visibleArea) (at C:/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:139)
    7. UnityEditor.PropertyHandler.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) (at C:/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:106)
    8. UnityEditor.PropertyHandler.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren, Rect visibleArea) (at C:/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:180)
    9. UnityEditor.PropertyHandler.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) (at C:/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:106)
    10. UnityEditor.PropertyHandler.OnGUILayout (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at C:/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:208)
    11. UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at C:/buildslave/unity/build/Editor/Mono/EditorGUI.cs:8791)
    12. UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at C:/buildslave/unity/build/Editor/Mono/EditorGUI.cs:8785)
    13. ItemDatabaseEditorWindow.DrawItemArea () (at Assets/Visual Item Database/Scripts/Editor/ItemDatabaseEditorWindow.cs:436)
    14. ItemDatabaseEditorWindow.OnGUI () (at Assets/Visual Item Database/Scripts/Editor/ItemDatabaseEditorWindow.cs:231)
    15. System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
    16. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    17. System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232)
    18. System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MethodBase.cs:115)
    19. UnityEditor.HostView.Invoke (System.String methodName, System.Object obj) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:295)
    20. UnityEditor.HostView.Invoke (System.String methodName) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:288)
    21. UnityEditor.HostView.InvokeOnGUI (Rect onGUIPosition) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:255)
    22. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
    What am I doing wrong? All I'm doing is adding an [EnumMask] attribute to a public variable derived from ItemBase.cs (I want every item of that type to have a set of toggleable flags)
     
  3. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    Hey!

    I understand your concern, but I need more information about this to help you. Do you mind sharing your code where you are using that attribute? If you don't want it to be public you can send it on my email (bloeys@outlook.com).

    Aside from that, the error message is saying that you are putting the attribute on a
    ItemSystem.Database.VIDItemListsV32

    variable, not on an enum.
    Please ensure that the variable that you are putting the attribute on is an enum.
     
  4. validname1

    validname1

    Joined:
    Feb 1, 2018
    Posts:
    23
    Hi.

    So my class looks like this

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace ItemSystem
    4. {
    5.     [System.Serializable]
    6.     public class ActorDefinition : ItemBase
    7.     {
    8.         public override bool IsActor() { return true; }
    9.      
    10.  
    11.         [EnumMask]
    12.         public Constants_Zeta.ActorFlags flags;
    13.  
    14.         public override void UpdateUniqueProperties(ItemBase itemToChangeTo)
    15.         {
    16.             base.UpdateUniqueProperties(itemToChangeTo);
    17.             ActorDefinition newMaterial = (ActorDefinition)itemToChangeTo;
    18.         }
    19.     }
    20. }
    and ActorFlags is declared like this

    Code (CSharp):
    1. [System.Flags]
    2.     public enum ActorFlags
    3.     {
    4.         Immortal = (1 << 0), // Don't take damage?
    5.         DamageableImmortal = (1 << 1), // Don't lose hp but do show damage dealt?
    6.     }
     
  5. validname1

    validname1

    Joined:
    Feb 1, 2018
    Posts:
    23
    It's not letting me edit my post so allow me to add: declaring the enummask attribute shown in ActorDefinition works in scripts attached to normal gameobjects where the inspector displays it properly without any errors. Unfortunately this seems to be the case for every single enum flag example I've found online. Removing the EnumMask attribute doesn't crash the editor so it's certainly the attribute that is causing it.
     
    Last edited: Jan 17, 2019
  6. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    So it seems the problem is with the attribute implementation on line 32 (which is making unity call that eventually fail)
    theEnum = fieldInfo.GetValue(property.serializedObject.targetObject);


    The problem is that this assumes that the script is on an object, however VID scripts are not monobehaviours and so this value will probably return null or something unexpected in this case, leading to the code to give an error about the types expected.

    You might want to post on the implementation page and ask whether this can be made to work on normal serializeable scripts on custom editor windows. I hope I can do something, but really the VID at that drawing stage simply calls the unity API and tells it draw, so any errors that happen are either on unity or as in this case, with some custom drawing attributes which unity calls.

    I hope you get it to work, but if you get anything else in the future or updates on this please feel free to contact me.

    Note:
    Your UpdateUniqueProperties code is incorrect, it should look like this example from the VID ItemMelee class:
    Code (CSharp):
    1. public override void UpdateUniqueProperties(ItemBase itemToChangeTo)
    2. {
    3.     ItemMelee melee = (ItemMelee)itemToChangeTo;
    4.  
    5.     Condition = melee.Condition;
    6.     CrushDamage = melee.CrushDamage;
    7.     EdgeDamage = melee.EdgeDamage;
    8.     PointDamage = melee.PointDamage;
    9. }
    Basically you need to copy the property values, not the class. In your case you are not getting a copy, but simply getting a reference to the item in the database, which will cause gameplay changes to affect the original item in the database.
     
    validname1 likes this.
  7. validname1

    validname1

    Joined:
    Feb 1, 2018
    Posts:
    23
    I see, so what if I had a hierarchy of classes that are deriving (ie Parent -> child -> child -> child)... Would I need to manually type out all of that again for every derived class? Or is there a quicker way to do it?
     
    Last edited: Jan 18, 2019
  8. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    If am not mistaken no, there is no need to do that. Each class has to just implement and update its own variables.
    Now if a class inherits from it, the child only has to call the 'base.' function and that so each class handles its own things.

    With that being said, I have never heard of people doing such inheritance with the VID, usually when you need something you just create a new type, although it might make sense in your specific case. But do keep in mind that composition (multiple smaller types used together) is in general preferred and is more flexible.
     
    validname1 likes this.
  9. validname1

    validname1

    Joined:
    Feb 1, 2018
    Posts:
    23
    Alright thanks, and yeah I use a lot of inheritance (ie ItemBase -> ItemWeapon -> ItemSword). So then I'll take the base call out of the first child and instead add it to the subsequent ones.
     
  10. maxaud

    maxaud

    Joined:
    Feb 12, 2016
    Posts:
    162
    Hello, looking to see if this will work for my needs and had a couple questions.
    1. Are each and every item in the database saved as a separate scriptable object?
    2. I’m looking at using this for many aspects of the game, from inventory items, to abilities, to enemy information, do you foresee any issues with doing so?
    3. Can you do advanced searching? Example: Get all weapons of a certain subtype that have damage over (int)100, that are (bool) marked as dealing earth damage, and are (string) blue in color?
    4. Are there any ways to import items from a spreadsheet? If not, could this be implemented for simple fields like int, string, bool, etc?
    5. Reading the documentation, there two ways to get an item, one by getitem and another by getitemcopy. When I use getitem and it changes the item in the database, does this change it forever? Even if I restart the game?
    6. Is there a way to add items to the database at runtime? Or add an existing item to a different type or subtype at runtime? Let’s say we name a type “Inventory” and wanted to move items to and from it? Or maybe move abilities to and from an “UnlockAbilities” type?
    7. Is there a way to create types and subtypes at runtime?
    8. Can there be multiple databases? Like if I used the above example for inventory and abilities, could these be separated and loaded for different save games? If not, I suppose the database item for these could have a field for what save game they belong to.
    Thank you!
     
  11. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    Hello Maxaud,

    Sorry I am late to reply, I have not received an email for some reason about a new post.

    Thank you for your interest in the VID, I'll try to answer as best as possible, but feel free to discuss and ask more ;)

    1. No, all VID items are stored in separate lists inside one scriptable object.

    2. There should be no problem whatsoever. I and many others using it (you can see in the reviews and I think the forum) have used it for different things. The only thing you need to do here is to setup your systems in a way to work best with the VID, and that is by making the VID hold all the data and then have your objects load that data and use it in different ways. The VID should usually not have real functionality (It's a database after all).

    3. Like that no, at least not by default, this seems more like a SQL query. You can get an entire subtype, so if your subtypes are super specific like that you can just get the entire subtype. But probably they are not, so instead (which is a nice addition for the VID and is super easy) is to have something like 'filter' functions, where you pass another function that does the checks and returns 'true' if the item is to be returned and 'false' if the item is not wanted.

    For speed I can make an implementation of this for you and in the future add it as a default VID feature/function.

    4. No, but this can for sure be implemented quite easily since the internal VID calls are exposed, so you would create your types that have the fields you want and then run a function that simply reads the excel sheet, create the different items and adds them to the database.

    5. If you are in the editor, then changes will be saved, but if you are in a build the changes are lost after the game is reloaded (I think it is also reset on scene reload, but you need to confirm this). This is a unity thing regarding how scriptable objects are handled.

    6. Types are classes and so you cannot simply 'move' an item from type to type. Similarly, item types are tied to a type. Really, with the inventory thing I feel this is outside the use of the VID, it is much more efficient in the case of an inventory to handle this via in game systems and make it use parts of the VID. For example, if your items stats don't change, your inventory can simply be a list of IDs/ItemEnums.

    Now the ability scenario is doable. Assuming all abilities are of the same type, then yes you can simply move the abilities from the 'Locked' subtype to the 'unlocked' subtype. Although wouldn't a simply bool be more efficient?

    7. Types no. Creating types does a lot of code generation for you. Subtypes yes, since all a subtype really is is a name, type and list of IDs.

    8. No, although I am considering that as a feature for the VID. The VID is best used as a database, and you don't usually have databases where 98% of the things are cloned from another. However, what people usually do as far as I know for saving loading and to have this kind of 'multiple database', is to use the JSONUtility from unity. This is super easy to use and serializes your classes in most cases.

    So what you do is on save, you take all the edited/new items of the database and convert to JSON with the utility. On load you simply load the json files you have into items and put them in the database. For deleting you can either simply ignore the items in the VID or have a list of items to be deleted, which can be run on load.


    I hope this has helped. If you need help implementing some of the things I mentioned I would be happy to help you with this as well. Wish you fun with the VID if you get it ;)
     
    maxaud likes this.
  12. boolean01

    boolean01

    Joined:
    Nov 16, 2013
    Posts:
    66
    I bought VID recently and so far, amazing asset.

    One minor tip though: I found none of my exported builds were working, even though VID seemed to work in the editor. I had to come to this thread and find a post from 2017 that says "Add the ItemSystemUtility prefab to the scene". Unless I missed it, there's nothing in the supplied documentation that mentions this!

    If this is a required step, you might want to add that in. Or have the prefab automatically placed in the scene when the database first gets initialized.
     
    bloeys and CarterG81 like this.
  13. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    Hey!
    Thanks for getting the VID. I am glad you are enjoying it :D

    I have, for some reason, always thought that was a documented thing. Going through the docs, I actually didn't find it anywhere where it says it is required:oops:.

    Thanks a lot for the note, I will update the asset page, the online docs file on the website and here as well to make sure people know that they need that!
     
    boolean01 likes this.
  14. Splatacat

    Splatacat

    Joined:
    Jan 10, 2013
    Posts:
    10
    Hi bloeys,

    I'm having difficulties updating unique properties of items on my custom class. I can change the properties in the getItemCopy instance, but then when I want to update those unique properties back to the game object it doesn't do it. update generic properties works fine.

    my custom class is:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace ItemSystem
    4. {
    5.     [System.Serializable]
    6.     public class ItemBuilding : ItemBase
    7.     {
    8.         [SerializeField, Range(1, 5), Header("Unique Properties")]
    9.         public int carryingStack;
    10.         public bool fitInInventory;
    11.         [SerializeField]
    12.         public bool partOfBuilding;
    13.  
    14.         public int CarryingStack
    15.         {
    16.             get { return carryingStack; }
    17.             set { carryingStack = value; }
    18.         }
    19.         public bool FitInInventory
    20.         {
    21.             get { return fitInInventory; }
    22.             set { fitInInventory = value; }
    23.         }
    24.  
    25.         public bool PartOfBuilding
    26.         {
    27.             get { return partOfBuilding; }
    28.             set { partOfBuilding = value; }
    29.         }
    30.  
    31.  
    32.  
    33.         public override void UpdateUniqueProperties(ItemBase itemToChangeTo)
    34.         {
    35.             ItemBuilding itb = (ItemBuilding)itemToChangeTo;
    36.  
    37.             CarryingStack = itb.CarryingStack;
    38.             FitInInventory = itb.FitInInventory;
    39.             PartOfBuilding = itb.PartOfBuilding;
    40.         }
    41.  
    42.         public void Break()
    43.         {
    44.         }
    and this is where I'm trying to update:
    Code (CSharp):
    1. ItemBuilding carriedItem = ItemSystemUtility.GetItemCopy<ItemBuilding>(hitObject.transform.GetComponent<ItemContainer>().item.itemID, ItemType.Building);
    2.                 carriedItem.partOfBuilding = true;
    3.                 carriedItem.weight = 25;         //For testing
    4.                 hitObject.transform.GetComponent<ItemContainer>().item.UpdateGenericProperties(carriedItem);
    5.                 hitObject.transform.GetComponent<ItemContainer>().item.UpdateUniqueProperties(carriedItem);
     
  15. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    Hello Splatacat,

    Thank you for getting the VID!
    Now about your question, from what I understand, you simply want to update an item on an item container from an edited item copy. In that case, why not simply assign it?

    Code (CSharp):
    1. ItemBuilding carriedItem = ItemSystemUtility.GetItemCopy<ItemBuilding>(hitObject.transform.GetComponent<ItemContainer>().item.itemID, ItemType.Building);
    2.                 carriedItem.partOfBuilding = true;
    3.                 carriedItem.weight = 25;         //For testing
    4.                 hitObject.transform.GetComponent<ItemContainer>().item = carriedItem;
    That is the easiest way, simply set the variable. In general, the update properties methods shouldn't be used, they are for internal VID usage. I don't see a case where a normal user would need them.

    Hopefully this fixes it :)
     
  16. Splatacat

    Splatacat

    Joined:
    Jan 10, 2013
    Posts:
    10
    Hi thanks for your reply,

    I tried that and the the variables from the item base change, but the variables from my custom class do not change at all.
     
  17. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    Sorry that you are facing problems, we will try to fix this as soon as possible ;)

    I was testing using the same class that you posted, and made a small testing script:
    Code (CSharp):
    1.     void Start()
    2.     {
    3.         ItemBuilding copy = ItemSystemUtility.GetItemCopy<ItemBuilding>((int)BuildingItems.Block, ItemType.Building);
    4.         Debug.Log("Old carrying stack: " + copy.CarryingStack);
    5.         Debug.Log("Old part of building: " + copy.PartOfBuilding);
    6.  
    7.         copy.carryingStack = 100;
    8.         copy.partOfBuilding = false;
    9.  
    10.         Debug.Log("New carrying stack: " + copy.CarryingStack);
    11.         Debug.Log("New part of building: " + copy.PartOfBuilding);
    12.  
    13.         GetComponent<ItemContainer>().item = copy;
    14.         ItemBuilding setItem = (ItemBuilding)GetComponent<ItemContainer>().item;
    15.         Debug.Log("Set carrying stack: " + setItem.CarryingStack);
    16.         Debug.Log("Set part of building: " + setItem.PartOfBuilding);
    17.     }
    Simply I am doing the same thing that you did code wise. I have an item prefab created by the VID, I only added to it the test script. The test script just gets a copy of the item, changes it and sets it to the item container.

    It prints the old values, the values of the copied item after being changed and the values that are shown after we set the ItemContainer.item variable. In this case, everything seems to be updated correctly.

    Your code looks fine, maybe you are facing problem because of something elsewhere. Can you please tell me a bit more of your setup, because so far I can not reproduce this. How are you creating your ItemContainer scripts?
    They are not the optimal way really (better to use ItemEnums in your own classes), but since you are using them, you should not add them manually, always through the VID (Update Object or Update Prefab(s) buttons).
     
  18. Splatacat

    Splatacat

    Joined:
    Jan 10, 2013
    Posts:
    10
    I am using the update prefabs button on a prefab of the gameobject i created with the same name as the item so it adds the item container to the prefab
     
  19. Splatacat

    Splatacat

    Joined:
    Jan 10, 2013
    Posts:
    10
    if i use the item enums to get a copy of the item from the database how do i then instantiate thats items prefab into the game world?
     
  20. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    It is very weird. I believe something in the middle, in your setup here is failing, because as far as the code you posted everything is fine. I am not sure if that is possible, but can you send me at least a small part of the project you have? Just the relevant parts that aren't working so that I can take a look at them.

    Now regarding your question about item enums, it is of course not mandatory and its my aim with the VID to make things as flexible as possible. However, if you ask my opinion, and the 'intended' design and use of the VID, things are ideally handled a bit differently.

    The Visual Item Database is best used as a data store, that is, a database. Store all your 'data' about any kind of game system/object in the VID, but put the logic in monobehaviours. Lets take the example of an enemy AI. Your Enemy script is the main controller, which might handle movement, shooting, cover etc... A normal monobehavior/Gameobject.

    Now you can make VID items act as the configuration or settings that actually control how the enemy works. So maybe you will have an EnemyProperties and Weapon VID types. These can have all the different options that control an enemy and what he uses, like speed, health, level, attack patterns etc...

    Your enemy script can then simply expose a public item enum for the enemy property and weapon, and then load them at start. So with one, or maybe just a few slightly different enemy scripts you can have a tremendous amount of customization and configurability, where all you have to do to completely change an enemy is to simply switch out the enemy property he is using.

    Separating your data from your logic can significantly reduce complexity and improve productivity, when done right. Let the VID handle your data, and you can focus on the logic. You can of course still put methods on the items, but in general the mono behvaior should handle it.

    You can now apply this style to almost any type of game (even your survival/building game) and it will work and give you all the benefits.

    Hopefully this helps, although feel free to discuss this further ;)
     
  21. lzardo2012

    lzardo2012

    Joined:
    Apr 11, 2013
    Posts:
    42
    Hello

    I´m just bought your asset and it seems great so far, but, not being a coder myself I´m having some doubts on how to approach it.

    The game I´m working on the player have access to modular Mechs and can replace any of its parts, such as legs, torso, hips, heads, etc... Each of those parts combine and modify the mech, for example, more strenght, accuracy, hit points, etc...

    The player can also choose different weapons, jetpacks and other itens

    Those parts needed to be also, upgradeable.

    Something like Diablo, with mechs

    What should be my approach to use your asset taking it into consideration? From a designer point of view and how can I explain it to the coder?

    And, if there are any scenes using the asset so I can have a better idea on how to use it?


    Thanks a lot for your attention
     
  22. bloeys

    bloeys

    Joined:
    Aug 26, 2014
    Posts:
    55
    Hey Lzardo2012,

    Thanks a lot for getting the VID!
    I hope you enjoy using it, and sorry for the late reply as I was quite busy.

    Your game sounds really awesome, and like a good fit for the VID.
    First of all, I suggest getting to know the basics of the VID (Which are very simple) by looking at the tutorial videos here and reading a bit in the docs if needed.


    After you get the general idea of how the VID functions we can go into how it is best used, and what I think would also best fit your game.

    I would point you to the following posts I made on this forum, they all discuss the philosophy behind how a project using the VID might be setup in a way that provides high flexibility.

    Please see:
    * [RELEASED]Visual Item Database - Game Items Management and Editing Tool
    * [RELEASED]Visual Item Database - Game Items Management and Editing Tool
    * [RELEASED]Visual Item Database - Game Items Management and Editing Tool


    Aside from these posts, here is an email I sent to someone asking about the usage of the VID:
    You can let your programmer read these posts and message to get an idea of how to setup the VID system. After that, if you guys have any questions at all please feel free to ask and I will help as much as possible.