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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Scriptableobject won't save in custom editor window

Discussion in 'Scripting' started by mlepp, Sep 12, 2015.

  1. mlepp

    mlepp

    Joined:
    May 22, 2013
    Posts:
    26
    I've recently getting into scriptableobjects and I'm in the process of creating an editor window for creating different kind of spells. The problem now is that when ever I make a change to a skill (which is a scriptableobject) the changes aren't saved and are reset after I switch between play and stop mode.

    The window flow:
    • First I create a .asset file which will store the spells (if there isn't one already)
    • Then I add new spells by clicking a button which creates the spells using CreateInstance<Spell>()
    • I draw the edit panel containing the controls needed for editing.
    • After editing I click the "Done" button.
    • When the "Done" button is clicked I set the entire database (which is now an .asset file) to Dirty using EditorUtility.SetDirty(_spells);
    Code snippet of when drawing/editing a spell:
    Code (csharp):
    1.  
    2. void DisplayEditMainArea()
    3.         {
    4.             EditorGUILayout.LabelField("Id: ", _selectedItem.Id);
    5.             _selectedItem.SkillName = EditorGUILayout.TextField("Name: ", _selectedItem.SkillName);
    6.             _selectedItem.Cooldown = EditorGUILayout.FloatField("Cooldown: ", _selectedItem.Cooldown);
    7.             _selectedItem.CastTime = EditorGUILayout.FloatField("Cast time: ", _selectedItem.CastTime);
    8.  
    9.             EditorGUILayout.Space();
    10.  
    11.             if (GUILayout.Button("Done", GUILayout.Width(100)))
    12.             {
    13.                 _skills.SortAlphabeticallyAtoZ();
    14.  
    15.                 EditorUtility.SetDirty(_skills);
    16.             }
    17.         }
    18.  
    I'm probably missing something obvious.
    But I'd appreciate all the help I could get.

    Thanks in advance.
     
  2. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,739
  3. mlepp

    mlepp

    Joined:
    May 22, 2013
    Posts:
    26
    Could maybe you give an example of how that would work? Pretty new to this.
     
  4. Serdan

    Serdan

    Joined:
    Sep 1, 2015
    Posts:
    10
    Code (CSharp):
    1. var serObj = new SerializedObject(_item);
    2.  
    3. EditorGUI.BeginChangeCheck();
    4.  
    5. EditorGUILayout.PropertyField(serObj.FindProperty("MyProperty"));
    6.  
    7. if(EditorGUI.EndChangeCheck())
    8. {
    9. serObj.ApplyModifiedProperties();
    10. EditorUtility.SetDirty(_item);
    11. }

    That's how I do it in my editor, which works.
     
  5. mlepp

    mlepp

    Joined:
    May 22, 2013
    Posts:
    26
    I got it working with both my code and your code as I noticed I had accidentally put a reset method in OnEnable on the scriptableobject.
    My question now is. Which way is preferred or recommended?
     
  6. Serdan

    Serdan

    Joined:
    Sep 1, 2015
    Posts:
    10
    Using SerializedObject is less code, since you can just use PropertyField. It also means you can use BeginChangeCheck to automatically update/setdirty when something is changed. The only problem is that you have to use strings, which won't get refactored if you change the name of a property. You can get around that by installing Roslyn and using the nameof() feature from C# 6.
     
  7. mlepp

    mlepp

    Joined:
    May 22, 2013
    Posts:
    26
    Okay I'll look into it, thanks.

    A second question as you seem to be good at scriptableobjects.
    My spells are constructed with a few nested scriptableobjects, like skill type (projectile etc.).
    My problem is now, that even after setting the scriptable object as dirty the changes aren't saved on the nested objects.

    I don't know if it's because I'm drawing them differently (HERE).

    Am I missing something about nested scriptableobjects?