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.
  2. Dismiss Notice

Resolved Items in List don't seem to get serialized properly

Discussion in 'Scripting' started by BrightBit, Feb 8, 2023.

  1. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    243
    I am trying to create a small and custom map editor to run in Unity itself. For that I basically wrote a Map class that stores several MapChunk instances. I can manipulate an instance of a Map because of a separate MapEditor class that implements an OnSceneGUI method.

    The problem: When I restart Unity the items in the Lists tileObjectKeys and tileObjectValues of the MapChunk instances contain wrong (outdated?) items.

    Does someone here know what I'm doing wrong?

    Here's a simplified version of my code that hopefully contains the problematic pieces:

    Code (csharp):
    1.  
    2. public class Map : MonoBehaviour
    3. {
    4.     [SerializeField] private List<MapChunk> chunks;
    5.  
    6.     public void ApplyChanges()
    7.     {
    8.         while (chunksToChange.Count > 0)
    9.         {
    10.             var chunk = chunksToChange.Dequeue();
    11.             var mask  = chunkChanges[chunk];
    12.  
    13.             chunk.Build(mask);
    14.  
    15.             chunkChanges[chunk] = UpdateMask.NONE;
    16.         }
    17.     }
    18. }
    19.  
    20. [CustomEditor(typeof(Map))]
    21. public class MapEditor : Editor
    22. {
    23.     [SerializeField] private Map map;
    24.  
    25.     private void OnEnable()
    26.     {
    27.         map = serializedObject.targetObject as Map;
    28.     }
    29.  
    30.  
    31.     private void OnSceneGUI(SceneView sceneView)
    32.     {
    33.         // do some mouse raycast logic
    34.  
    35.         if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
    36.         {
    37.             OnMouseDown(tilePos);
    38.         }
    39.  
    40.         map.ApplyChanges();
    41.  
    42.         sceneView.Repaint();
    43.     }
    44.  
    45.     private void OnMouseDown(Vector2Int tilePos)
    46.     {
    47.         if (paletteIndex >= palette.Count) return;
    48.  
    49.         var item = palette[paletteIndex].GetComponent<TileObject>();
    50.  
    51.         if (item == null) return;
    52.  
    53.         map.SetTileObject(tilePos, item);
    54.  
    55.         serializedObject.ApplyModifiedProperties();
    56.     }
    57. }
    58.  
    59. [Serializable]
    60. public class MapChunk : MonoBehaviour
    61. {
    62.     [SerializeField] private List<Vector2Int> tileObjectKeys;
    63.     [SerializeField] private List<TileObject> tileObjectValues;
    64.  
    65.     // initialization methods would go here
    66.  
    67.     public void SetTileObject(Vector2Int tilePos, TileObject tileObject)
    68.     {
    69.         // tileObjects[tilePos] = tileObject;
    70.  
    71.         for (var i = 0; i < tileObjectKeys.Count; ++i)
    72.         {
    73.             var key = tileObjectKeys[i];
    74.  
    75.             if (key != tilePos) continue;
    76.  
    77.             tileObjectValues[i] = tileObject;
    78.             return;
    79.         }
    80.  
    81.         tileObjectKeys.Add(tilePos);
    82.         tileObjectValues.Add(tileObject);
    83.     }
    84.  
    85.     public void RemoveTileObject(Vector2Int tilePos)
    86.     {
    87.         // tileObjects.Remove(tilePos);
    88.  
    89.         for (var i = 0; i < tileObjectKeys.Count; ++i)
    90.         {
    91.             var key = tileObjectKeys[i];
    92.  
    93.             if (key != tilePos) continue;
    94.  
    95.             tileObjectKeys.RemoveAt(i);
    96.             tileObjectValues.RemoveAt(i);
    97.             return;
    98.         }
    99.     }
    100. }
    101.  
    102.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,713
    I see you doing the .ApplyModifiedProperties but I'm not sure that's enough or if it covers all you have in flux there.

    Generally if you modify things in editor code you need to inform Unity that they are dirty, either with the various SetDirty() calls or else with the Undo.RecordObject() mechanism. Are you doing this?
     
  3. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    243
    No. :) ...and as it turns out the EditorUtility.SetDirty() method was all I needed.

    Thank you Kurt-Decker. That was exactly what I was looking for.
     
    SF_FrankvHoof and Kurt-Dekker like this.