Search Unity

Reorderable List v2

Discussion in 'Immediate Mode GUI (IMGUI)' started by CDF, Jul 9, 2015.

  1. YaserDev

    YaserDev

    Joined:
    Aug 17, 2016
    Posts:
    19
    Hello.
    I have added the package to my project, but I can't use the directory Malee, it says it's not found.
    I have tried adding a reference to it in visual studio, by right-clicking the project assembly, then AddReferernce, but I get an error when I try to add the Rotorz package that says it can't be added, without any other message.
    Has anyone faced such a problem?
    Thanks
    (Nevermind: Turns out Malee is not the directory of the package itself, but it was in the example on git hub, I used it before but accidentally deleted the folder)
     
    Last edited: Mar 16, 2018
  2. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    713
    Hey just a small update here, I've added some new features to the ReorderableList:

    pagination - ability to separate the list into pages, helpful if you're dealing with massive lists
    sorting - ability to sort list based on a field, or the value of each element
    custom label per element - "getElementLabelCallback"

    Let me know what you think, and any bugs you might find :)
     
    alexanderameye likes this.
  3. ferdielance

    ferdielance

    Joined:
    May 31, 2018
    Posts:
    1
    I just discovered this library and it's working perfectly. I was trying to display a list of objects with various custom drawers, and nothing else worked smoothly; this made my life much easier. Thanks a lot!
     
  4. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    912
    Hey, is there a way to know if a certain list element was selected and return it as a Boolean in code?

    Thanks in advance,

    Alex
     
  5. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    713
    You can get selection indices and loop over:

    Code (CSharp):
    1. var selected = list.Selected;
    2.  
    3. foreach (int index in selected) {
    4.  
    5.     var element = list.GetItem(index);
    6. }
     
    alexanderameye likes this.
  6. TylerO

    TylerO

    Joined:
    Aug 21, 2011
    Posts:
    32
    To add to the following answer above, when you get an item by Index, how do you cast it back to it's original object? I have tried to do the following, but it doesn't seem to work:

    Code (CSharp):
    1.  
    2. foreach (int index in selectedIndexes)
    3. {
    4.     selectedProperty = itemList.GetItem(index);
    5.     selectedItem = (ItemDefinition)selectedProperty.objectReferenceValue;
    6. }
    7.  

    Great plugin, just need to figure out the above before I can move forward haha
     
  7. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    713
    your list/array is of ItemDefinition type?
    Is ItemDefinition an actual unity object?
    what errors are you getting?
     
  8. TylerO

    TylerO

    Joined:
    Aug 21, 2011
    Posts:
    32
    Hi @CDF, thanks for the quick reply!

    Following the examples, I wrote the following:

    Code (CSharp):
    1.  
    2.     [Serializable]
    3.     public class ItemDefinition : UnityEngine.Object
    4.     {
    5.         /// <summary>
    6.         /// The unique of ID of this item definition
    7.         /// </summary>
    8.         public int id;
    9.         public string itemName;
    10.  
    11.         public bool canCraft;
    12.         public bool canGenerate;
    13.  
    14.         //  Item Appearance
    15.         //      Position
    16.         //      Rotation
    17.         //      Scale
    18.         //      Models variation based on Race/Gender
    19.         public List<ItemObject> objects;
    20.  
    21.         //  Item Recipe
    22.         public ItemRecipe recipe;
    23.  
    24.         //  Item Set
    25.         public ItemSet set;
    26.     }
    27.  
    28.     [Serializable]
    29.     public class ItemDefinitionList : ReorderableArray<ItemDefinition> {  }
    30.  
    ItemDefinition does indeed inherit UnityEngine.Object and the actual ReorderableList is using the ItemDefinitionList. It was my understanding that the 'GetItem' method would return an item from the ReorderableArray of ItemDefinitionList, which, is an ItemDefintion.

    If my understanding is incorrect, please let me know - as for the error, `selectedItem` is null. If you have any other questions, please do not hesitate to ask - and I appreciate the help very much!

    Edit:

    If it helps, here is also the ItemDatabase class (which contains the ItemDefinitionList with the 'Reorderable' attribute)


    Code (CSharp):
    1.  
    2. public class ItemDatabase : ScriptableObject
    3. {
    4.     [SerializeField, Reorderable]
    5.     public ItemDefinitionList itemDefinitionList;
    6. }
    7.  
    As well as how the ReorderableList is setup:

    Code (CSharp):
    1.  
    2. // Do we have an existing ItemDatabase?
    3. itemDatabase = Resources.Load<ItemDatabase>("Assets/Databases/ItemDatabase.asset");
    4. if (itemDatabase == null)
    5. {
    6.     // Create a new ItemDatabase
    7.     itemDatabase = (ItemDatabase)ScriptableObject.CreateInstance("ItemDatabase");
    8.     // Save it
    9.     AssetDatabase.CreateAsset(itemDatabase, "Assets/Databases/ItemDatabase.asset");
    10.     AssetDatabase.SaveAssets();
    11. }
    12. // Create our Item Definition List
    13. itemDbSerialized = new SerializedObject(itemDatabase);
    14. itemList = new ReorderableList(itemDbSerialized.FindProperty("itemDefinitionList"), true, true, false, ReorderableList.ElementDisplayType.Auto, "Item Definitions", null);
    15.  
     
    Last edited: Dec 18, 2018
  9. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    713
    The issue is that ItemDefinition extends UnityEngine.Object
    Unity doesn't create UnityEngine.Objects automatically for you, so the reference will always be null unless you assign an object to it.

    So how to do assign an object to an entry in the array?

    extend from ScriptableObject. And use the "CreateAssetMenu" attribute:

    Code (CSharp):
    1. [CreateAssetMenu]
    2. public class ItemDefinition : ScriptableObject {
    Now you can create an "ItemDefinition" object in your project, then drag and drop that asset into the list inspector.

    If your intention was to simply use a default C# object. Then just define the class like so:

    Code (CSharp):
    1. [Serializable]
    2. public class ItemDefinition {
    Now, because ItemDefinition is just a class and is Serializable, the Unity serializer can automatically generate and serialize your object.

    Hope that makes sense.
    Try changing this:

    Code (CSharp):
    1. [SerializeField, Reorderable]
    2. public ItemDefinitionList itemDefinitionList;
    to

    Code (CSharp):
    1. [SerializeField]
    2. public ItemDefinition[] itemDefinitionList;
    And see how Unity renders the inspector window. You'll notice an array accepting Object references, and as above, you're responsible for creating and assigning the references when a class inherits from UnityEngine.Object.

    *EDIT*
    I realize the documentation is lacking, I'm just too busy with work to actually do anything about. It is something I'm always thinking about though ;)
     
  10. TylerO

    TylerO

    Joined:
    Aug 21, 2011
    Posts:
    32
    It might be worth mentioning that I am actually working with an Editor Window, not an inspector.

    Ideally, I would like to keep it to where adding an ItemDefinition is as simple as pressing the 'add' button in the ReorderableList, as opposed to creating an instance of a ScriptableObject and assigning it (although, I suppose I could override what the add button does) so having ItemDefinition as just a class would be ideal.

    And I think I understand what you're getting at - I don't actually need an ItemDefinitionList class (which I explicitly created for the ReorderableArray) and instead, I should just be able to created a ReorderableList from the array (or list?) of ItemDefinitions - am I correct in that thinking?

    I'll take the above and work on making changes to my code. Again, thanks for the help :)
     
  11. Totoro83y

    Totoro83y

    Joined:
    Sep 21, 2013
    Posts:
    9
    Hi, first of all I want to say thanks for this great plugin.

    Next, I'm having a very strange bug (or at least it seems so), and I'm not sure if it is about your software or unity itself.

    If I don't add any function in the event drawElementCallback all works as espected.
    Instead, if I insert a very simple function that mimics the plugin normal behaviour, like this:
    Code (CSharp):
    1.     private void Element(Rect rect, SerializedProperty element, GUIContent label, bool selected, bool focused)
    2.     {
    3.         EditorGUI.PropertyField(rect, element, label, true);
    4.     }
    it works but all the editing elements in the TextFields are not showed. I don't see any highlight in text, any caret, anything at all. The TextFields works as expected even if they are not showed, I can edit anything, select anything, just I don't see them...
     
    Last edited: Apr 24, 2019
  12. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    713
    Hmm, I can't reproduce it. There must be something else capturing focus if you're not seeing a caret.
    Have you tried doing this in an empty project?

    For reference, here's the code inside ReorderableList that handles drawing elements:
    Code (CSharp):
    1.  
    2. if (drawElementCallback != null) {
    3.  
    4.     drawElementCallback(renderRect, element, label, selected, focused);
    5. }
    6. else {
    7.  
    8.     EditorGUI.PropertyField(renderRect, element, label, true);
    9. }
    10.  
    So I can't see why implementing drawElementCallback and doing the exact same thing wouldn't work!
     
  13. Totoro83y

    Totoro83y

    Joined:
    Sep 21, 2013
    Posts:
    9
    I don't think the problem is just the focus captured elsewhere because I can't even see the highlights in text, if I try to select it.
    It is a very strange problem, and I had it in another piece of code, too, so I'm starting to think that it is a bug of the current unity version (2019.1.0f2). However I didn't try with a very simple and minimal project so I'm not sure.