Search Unity

ScriptableObject Problem

Discussion in 'Scripting' started by RvBGames, Feb 24, 2014.

  1. RvBGames

    RvBGames

    Joined:
    Oct 22, 2013
    Posts:
    141
    I've read a rather decent posting regarding scriptable objects, and the proper way of setting them up. However, my implementation doesn't seem to work. Would someone be willing to review the code below and let me know if they spot what I'm doing wrong.

    The three classes are contained in their own source file with the same name as the class. Additionally, the MonoBehavior class is attached to a game object in the scene.

    Code (csharp):
    1.  
    2. [Serializable]
    3. public class PlayerProfile : ScriptableObject
    4. {
    5.     public int playerIndex;
    6.     public string playerName;
    7. }
    8.  

    Code (csharp):
    1.  
    2. [Serializable]
    3. public class PlayerManager : ScriptableObject
    4. {
    5.     public List<PlayerProfile> players;
    6.  
    7.  
    8.     void OnEnable()
    9.     {
    10.         if(players == null)
    11.             players = new List<PlayerProfile>();
    12.     }
    13. }
    14.  


    Code (csharp):
    1.  
    2. public class Test : MonoBehavior
    3. {
    4.     public PlayerManager playerManager;
    5.  
    6.  
    7.     void OnEnable()
    8.     {
    9.         if(playerManager == null)
    10.             playerManager = ScriptableObject.CreateInstance<PlayerManager>();
    11.  
    12.         playerManager.players.Add(ScriptableObject.CreateInstance<PlayerProfile>());
    13.     }
    14. }
    15.  
     
    Last edited: Feb 24, 2014
  2. RvBGames

    RvBGames

    Joined:
    Oct 22, 2013
    Posts:
    141
    Probably stupidity on my part. Based on this thread http://forum.unity3d.com/threads/100027-Saving-Loading-ScriptableObject-problem I should be able to add two functions to load/save the data:

    Code (csharp):
    1.  
    2. void LoadPlayerManager()
    3. {
    4.     playerManager = (PlayerManager)AssetDatabase.LoadAssetAtPath(@"Assets\Resources\Menu\PlayerManager.asset", typeof(PlayerManager));
    5.  
    6.  
    7.     if(playerManager == null)
    8.     {
    9.         AssetDatabase.CreateAsset(playerManager, @"Assets\Resources\Menu\PlayerManager.asset");
    10.         playerManager = (PlayerManager)ScriptableObject.CreateInstance(typeof(PlayerManager));
    11.     }
    12. }
    13.  
    14.  
    15.  
    16. void SavePlayerManager()
    17. {
    18.     if(!AssetDatabase.Contains(PlayerManager))
    19.         AssetDatabase.CreateAsset(PlayerManager, @"Assets\Resources\Menu\PlayerManager.asset");
    20.  
    21.     AssetDatabase.SaveAssets();
    22. }
    23.  
    Would someone please confirm if this is the proper way of doing this. Also I'm a little concerned about the SaveAssets call at the bottom, since it appears to save all assets. Is there a call just for the specific asset?
     
    Last edited: Feb 24, 2014
  3. RvBGames

    RvBGames

    Joined:
    Oct 22, 2013
    Posts:
    141
    Unfortunately AssetDatabase is within the UnityEditor namespace.

    Does anyone know how to properly serialize scriptableobjects at runtime?
     
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    You can't, and for good reason. Why would you want to create asset from a deployed game?
     
  5. RvBGames

    RvBGames

    Joined:
    Oct 22, 2013
    Posts:
    141
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
  7. RvBGames

    RvBGames

    Joined:
    Oct 22, 2013
    Posts:
    141
    That entire talk about serialization, and the Mega Post about best practices is extremely limited and should be noted up front. It's only useful in an editor context. Fine. . .but it is limited.

    Serialization and Deserialization in the editor, and Deserialization in the runtime.
     
  8. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    It's not really made for saving games or anything like that... it's made for generating and saving data up front. For instance, if you have something that you need to create procedurally, but only once... then you can do all of your generation up front in the editor, save it out to the asset database, and read all of that in at runtime. If you're needing to serialize and save things that are changing, this is done in persistent storage and you'll need to look at other methods of serialization such as JSON, BSON or XML, depending on your platform and/or requirements.
     
  9. RvBGames

    RvBGames

    Joined:
    Oct 22, 2013
    Posts:
    141
    I use scriptableobjects heavily with our assets. However, it never crossed my mind that the same functionality wouldn't be available at runtime.
     
  10. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Many platform does not support you writing generic files on disc. So, usual .asset serialization is not reliable. It's why most people will go for text base serialization when they must have some at runtime.
     
  11. RvBGames

    RvBGames

    Joined:
    Oct 22, 2013
    Posts:
    141
    LightStriker, can you give me a specific example of a platform that doesn't allow you to write to disc?
     
  12. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    WebPlayer, iOS/Android/Wii/360/PS3 (with some limitation, I think you only have access to only one specific folder)
     
  13. RvBGames

    RvBGames

    Joined:
    Oct 22, 2013
    Posts:
    141
    I can understand why web player would be a problem. Are the restrictions with the other platforms a Unity limitation?
     
  14. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    No, it's a platform limitation. For good reason, iOS/Android doesn't let you write or read everywhere. Usually, they make a specific directory just for the apps.