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

Question Variables Being Assigned in Editor Script Resetting on Start

Discussion in 'Scripting' started by Mashimaro7, Aug 10, 2023.

  1. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    I was using findObjectsOfType in awake to assign all the object indexes in the scene, but it was sometimes giving different indexes when i changed scenes, so i wrote a script that lets me assign the indexes in the editor, here's the code,
    Code (CSharp):
    1.     public void AssignItemIndexes()
    2.     {
    3.         saveAbles = FindObjectsOfType<MonoBehaviour>().OfType<ISaveAble>().ToArray();
    4.  
    5.         for (int i = 0; i < saveAbles.Length; i++)
    6.         {
    7.             saveAbles[i].Index = i;
    8.         }
    9.        
    10.     }
    The interface looks like this,
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public interface ISaveAble {
    4.     public int Index { get; set; }
    5.  
    6.     public void CheckAvailability();
    7.  
    8.     public MonoBehaviour MonoBehaviour { get;  }
    9.  
    10.     public bool spawnedDrop { get; set; }
    11.  
    12. }
    13.  
    It's attached to multiple classes. But for some reason it's being reset to 0 every time i change scenes(even if i change scenes in the editor). The numbers get assigned, i can see them assigned in the editor, but they reset to 0. I tried changing one manually and it doesn't reset, so one of them is set to 5 and all the others go back to 0 lol.

    Is there something i'm doing wrong? I tried saving the scene and it doesn't seem to fix it...
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Whenever you modify values via code that you intend to save, you need to Unity that you have done so, otherwise it doesn't know to write the new values to disk.

    This is often done via 'dirtying' the relevent assets, such as with the following method: https://docs.unity3d.com/ScriptReference/EditorUtility.SetDirty.html
     
  3. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    I've seen "SetDirty" before and never knew what it meant haha. What do i set dirty? Can't seem to set the gameobject, the interface, or the monobehavior.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    It takes a UnityEngine.Object as a parameter. So a component or game object should work.

    So whatever asset you're modifying, set that dirty. This will dirty the scene if the object lives inside of one.
     
    Mashimaro7 likes this.
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    Since your "Index" is a property in your interface, are you sure that the actual implementation in the actual classes has the backing field serialized? You should have shown one of your implementations. Unity does not serialize properties at all, only fields. If you implement an auto-property the implicit backing field is a private field that isn't serialized unless you use
    [field:SerializeField]
    on the auto-property.

    Like Spiney said, modifications has to be communicated. In your code above you would do:

    Code (CSharp):
    1.         for (int i = 0; i < saveAbles.Length; i++)
    2.         {
    3.             Undo.RecordObject((UnityEngine.Object)saveAbles[i], "Assigned Item index");
    4.             saveAbles[i].Index = i;
    5.         }
    Note that RecordObject has to be called BEFORE the actual change. It records the undo state of the object and at the end of the current input cycle it would diff the current state with the recorded one.
     
    Mashimaro7 and spiney199 like this.
  6. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    Thank you, i didn't realize i needed to use EditorUtilities.SetDirty(), I was having trouble finding the namespace haha.

    Oh, is this a better method? It seems to have worked with SetDirty, but ill do this if it's better.