Search Unity

  1. New Unity Live Help updates. Check them out here!

    Dismiss Notice

Trying to set ScriptableObject as dirty

Discussion in 'Scripting' started by UnityGenericAnon, Jan 20, 2020.

  1. UnityGenericAnon

    UnityGenericAnon

    Joined:
    Sep 24, 2019
    Posts:
    70
    I'm using a custom editor for a ScriptableObject, and every time I restart Unity, almost all its data is reset (everything except an enum). I read 3 Unity Answers threads, and 2 forum threads, and so far what I know is I have to set the ScriptableObject as dirty using "EditorUtility.SetDirty()", however I have no idea where exactly to use this, or what to put in the brackets (if anything).

    I think I need to put it somewhere in the custom editor script, but that's about it. All the threads' answers are really vague, they all just say something along the lines of "use EditorUtility.SetDirty()", but give no specifics as to how or where to use it.

    I read the Unity manual/scripting API page, but that didn't help.
     
    Last edited: Jan 20, 2020
  2. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    551
    Where/how do you modify the value(s) ? Are those data fields tagged as System.Serializable (for custom types), and is either public or (better) tagged with the SerializedField attribute ?

    In any case, if you want unity to write your changes to the disk you have to save the current scene or your changes only live in your RAM and thus are lost when restarting Unity.

    Considering you've written the serialization parts correctly:
    - if you're doing changes from the editor, then you're only missing the saving the scene part
    - if you're doing changes from an editor script, then what you said about the EditorUtility.SetDirty() then saving. To call this simple put your scriptable object reference as parameter and it will tell unity there's something that needs to be saved to the disk next time the scene is saved.

    Following all this, if you still struggling consider posting the data storage part of your scriptable object so someone can pinpoint what you forgot.
     
  3. UnityGenericAnon

    UnityGenericAnon

    Joined:
    Sep 24, 2019
    Posts:
    70
    The values currently aren't being modified aside from me manually typing in values in the inspector, after selecting the ScriptableObject instance in the Project window. All the values are currently public.

    The scriptable objects will just be storage for references (e.g. how much ammo a certain gun can hold), and I'm not planning on editing their values beyond that.

    Here's the whole ScriptableObject script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [CreateAssetMenu(menuName = "Custom/Weapon")]
    6. public class WeaponScriptable : ScriptableObject {
    7.  
    8.     public enum WeaponType {
    9.  
    10.         Melee,
    11.         Gun
    12.     };
    13.  
    14.     public WeaponType weaponType;
    15.  
    16.     // Universal stats
    17.     public int damage;
    18.     public float range;
    19.  
    20.     // Melee stats
    21.     public float swingSpeed;
    22.  
    23.     // Gun stats
    24.     public float recoil;
    25.     public int magazineSize;
    26.     public float reloadTime;
    27.     //public float fireRate;
    28. }
    I always do CTRL+S before closing Unity, and just now I tried that and then also going to File > Save.
     
  4. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    551
    Serialization part is fine, have you tried saving after editing your values ?

    You should be able to see the changes in your versionning tool commit list to confirm it was well saved to the disk.
     
  5. UnityGenericAnon

    UnityGenericAnon

    Joined:
    Sep 24, 2019
    Posts:
    70
    Could you clarify what you mean by "versionning tool commit list"? As in, where I can find it.
     
    Last edited: Jan 20, 2020
  6. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    551
    Well that's too bad if you're not using versionning, you should consider it.

    Sorry this is beyond the scope of your question but since you asked, versionning is an external tool that saves your files in such fashion that it can tell what changed from a version to another of each file.

    Several softwares exist such as git, and unity itself also offers the feature and calls it Collaborate. you can enable it in the services menu from the editor... I strongly recommend you watch some tutorials on the subject and start using this, makes your life as video game dev a whole lot better. https://docs.unity3d.com/560/Documentation/Manual/UnityCollaborateSettingUp.html

    If you had this setup, it'd be easy to see whether your file was properly edited & saved by unity...

    But I guess you can also open the file with a simple text editor and check it out manually if thats your thing.
     
    UnityGenericAnon likes this.
  7. UnityGenericAnon

    UnityGenericAnon

    Joined:
    Sep 24, 2019
    Posts:
    70
    Yeah, it wasn't saving. Opened the file in Notepad++ while Unity was still open, and all the int and float values were on zero. Apparently I have to actually have my mouse over the ScriptableObject inspector window when I do CTRL+S, and it saves now.

    Thank you, and I'll check those tools out too.
     
    Last edited: Jan 20, 2020
    _met44 likes this.
  8. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    204
    When you make changes to a
    SerializedObject
    , you have to tell Unity that the object changed and that the changes should be applied. You do this by calling the function that you mentioned, giving the changed object as argument. See for instance:

    Code (CSharp):
    1. ScriptableObject target = this;
    2. SerializedObject so = new SerializedObject(target);
    3.  
    4. // property fields and such
    5.  
    6. so.ApplyModifiedProperties();
    When creating a new object from an editor:
    Code (CSharp):
    1. // MyScriptableObject : ScriptableObject
    2. MyScriptableObject asset = ScriptableObject.CreateInstance<MyScriptableObject>();
    3. AssetDatabase.CreateAsset(asset, AssetDatabase.GenerateUniqueAssetPath(path + "/" + name + ".asset"));
    4.  
    5. asset.SomeProperty = someValue;
    6.  
    7. EditorUtility.SetDirty(asset);
    Note that this requires you to manually save your project (not scene). You can also call
    AssetDatabase.SaveAssets()
    and
    AssetDatabase.Refresh()
    to save your new asset from code.
     
  9. UnityGenericAnon

    UnityGenericAnon

    Joined:
    Sep 24, 2019
    Posts:
    70
    Weird thing is, I have to also click on one of these;
    upload_2020-1-20_15-7-30.png
    before I can actually save. Clicking and/or hovering over the inspector window (even after clicking on a field and changing the value) alone doesn't let me save.
     

    Attached Files:

  10. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    409
    Also make sure to use PropertyField to draw all the fields in your custom editor (I'm presuming that you're using IMGUI and not UIElements).
     
    UnityGenericAnon likes this.
  11. UnityGenericAnon

    UnityGenericAnon

    Joined:
    Sep 24, 2019
    Posts:
    70
    Yep, using IMGUI. Thanks.
     
unityunity