Search Unity

Temporary Values in a Reorderable List

Discussion in 'Scripting' started by Camronas, Mar 27, 2019.

  1. Camronas

    Camronas

    Joined:
    Apr 20, 2012
    Posts:
    154
    Hey everyone, so I am trying to make a "Token" class which will help me when saving data. I want to have things like Items, Spells, Classes, Races, etc stored in their own Database so when saving the object I can save the index because as far as I am aware I cannot serialize ScriptableObjects.

    Everything is working rather well expect for working in a Reorderable List.

    The scripts thus far:

    Code (CSharp):
    1. [System.Serializable]
    2. public class ClassToken
    3. {
    4.     [SerializeField] public int curExp;
    5.     [SerializeField] public int curLevel;
    6.     [SerializeField] public int index;
    7. }
    This is the Class Token script, it is used to save a character's level and current experience within a class. For example if they train into being a Fighter they might be a level 1 fighter. The index value stores where in the Class database it is stored. This way I can still serialize the location of the ScriptableObjects even though I can serialize the object itself.

    Code (CSharp):
    1.         _curCB = target as CharacterBase;
    2.         _curCB.InitCharacter();
    3.  
    4.         //Find the vital and attribute properties
    5.         _vitalArray = serializedObject.FindProperty("_vitals");
    6.         _attributeArray = serializedObject.FindProperty("_attributes");
    7.         _characterClassesList = serializedObject.FindProperty("_characterClasses");
    8.  
    9.         _classList = new ReorderableList(serializedObject, _characterClassesList, true, true, true, true);
    10.         _classList.drawHeaderCallback = rect => { EditorGUI.LabelField(rect, "Classes"); };
    11.         _classList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocus) =>
    12.         {
    13.             var element = _classList.serializedProperty.GetArrayElementAtIndex(index);
    14.             GUILayout.BeginHorizontal();
    15.  
    16.             EditorGUI.LabelField(new Rect(rect.x, rect.y, 75, EditorGUIUtility.singleLineHeight), "Cur Level: ");
    17.             element.FindPropertyRelative("curLevel").intValue = EditorGUI.IntField(new Rect(rect.x + 75, rect.y, 50, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("curLevel").intValue);
    18.  
    19.             EditorGUI.LabelField(new Rect(rect.x + 140, rect.y, 75, EditorGUIUtility.singleLineHeight), "Cur Exp: ");
    20.             element.FindPropertyRelative("curExp").intValue = EditorGUI.IntField(new Rect(rect.x + 210, rect.y, 50, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("curExp").intValue);
    21.  
    22.             EditorGUI.LabelField(new Rect(rect.x + 280, rect.y, 75, EditorGUIUtility.singleLineHeight), "Class: ");
    23.  
    24.             ClassBase loadedClass = GameManager.instance.CharacterClassDatabase.databaseElements[element.FindPropertyRelative("index").intValue] as ClassBase;
    25.             loadedClass = EditorGUILayout.ObjectField(loadedClass, typeof(ClassBase), true) as ClassBase;
    26.             element.FindPropertyRelative("index").intValue = loadedClass.Index;
    27.  
    28.             GUILayout.EndHorizontal();
    29.         };
    This is the code within the CharacterBase_Editor which sets up my ReorderableList. This current version works perfectly fine with one exception:
    Example1.jpg

    As you can see in the attached image the object fields are drawn outside of the List. I have tried to draw them inside the list using:
    Code (CSharp):
    1. EditorGUI.ObjectField
    However it requires a SerializedProperty which I don't have. Everything else is working exactly how I want it. Apart from that one thing.

    Any help would be appreciated!
     
  2. Camronas

    Camronas

    Joined:
    Apr 20, 2012
    Posts:
    154
    Figured it out! Turns out there is an overload of the EditorGUI.ObjectField function which doesn't require a SerializedProperty.

    Code (CSharp):
    1.             ClassBase loadedClass = GameManager.instance.CharacterClassDatabase.databaseElements[element.FindPropertyRelative("index").intValue] as ClassBase;
    2.             loadedClass = EditorGUI.ObjectField(new Rect(rect.x + 325, rect.y, 100, EditorGUIUtility.singleLineHeight), loadedClass, typeof(ClassBase), false) as ClassBase;
    3.             element.FindPropertyRelative("index").intValue = loadedClass.Index;
    Thanks to anyone who took a look, and I am providing the answer in case anyone else comes across the same issue.

    Example1.jpg
     
    WheresMommy likes this.