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

[RELEASED] Odin Inspector & Serializer - The Ultimate Workflow Tool ★★★★★

Discussion in 'Assets and Asset Store' started by jorisshh, Jun 15, 2017.

  1. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Thanks for the report. What version of Odin do you have? I think that error should be fixed in the latest Odin - 1.0.6.9 - Or actually, it may not have made it in.

    Edit: Actually I'm not sure, it may be fixed in 1.0.6.9, could you test that and see if that works? If not, I have a nother possible hotfix for you - if you could pm me your Odin invoice ID, I'll send you the hotfix to you right away so we can see if that fixes it.
     
    Last edited: May 17, 2018
  2. jsizemore

    jsizemore

    Joined:
    May 14, 2018
    Posts:
    3
    Looks like I'm almost there. I've incorporated the snippet of code above, as shown below:

    Code (CSharp):
    1.             // Odin serialization stuff
    2.             string path = Path.Combine(Application.streamingAssetsPath, "serializetest.gd");
    3.  
    4.             SerializeTest original = DebugLoadout.Instance.GetComponent<SerializeTest>();
    5.  
    6.             byte[] bytes = SerializationUtility.SerializeValue<SerializeTest>(original, DataFormat.Binary);
    7.             using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write))
    8.             using (var writer = new BinaryWriter(fs))
    9.             {
    10.                 writer.Write(bytes);
    11.             }
    12.  
    13.             SerializeTest deserialize;
    14.             using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
    15.             using (var reader = new BinaryReader(fs))
    16.             {
    17.                 deserialize = SerializationUtility.DeserializeValue<SerializeTest>(reader.BaseStream, DataFormat.Binary);
    18.             }
    19.  
    20.             bool originalNull = original == null;
    21.             bool deserializeNull = deserialize == null;
    22.  
    where my SerializeTest class looks like the following:

    Code (CSharp):
    1. using Sirenix.OdinInspector;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class SerializeTest : SerializedMonoBehaviour
    7. {
    8.  
    9.     public int x = 1;
    10. }
    After I run the code shown in the first snippet, this what I get in the watch window if I set a breakpoint right after the deserialization:

    screenshot.png

    The weird thing is that my data is clearly there - you can see x is still equal to 1, but Unity thinks the deserialize object is null (check the bools at the bottom of my first code snippet and the bottom of the watch window). The same result happens on more complicated objects that I serialize/deserialize. I went with my SerializeTest class because it's a simple example, but I have other objects I'm can deserialize with all the correct data, but Unity still thinks they are null. In addition, I am still getting the following error in my log, which I'm assuming has something to do with this:

    error.png
    Any ideas on what's happening?
     
  3. RuneSoegaard

    RuneSoegaard

    Joined:
    Feb 22, 2017
    Posts:
    5
    Hi there!

    I am trying to use Odin Serializer to save my data from a dictionary within a dictionary, but when I add a new dictionary inside the other dictionary at play mode, it is gone when I exit play mode again. I am quite new to this subject so I hope anybody can help me.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Sirenix.OdinInspector;
    5. using Sirenix.Serialization;
    6.  
    7.  
    8. public class SavedFacialExpressions : SerializedMonoBehaviour {
    9.  
    10.     [DictionaryDrawerSettings(DisplayMode = DictionaryDisplayOptions.ExpandedFoldout)]
    11.     [OdinSerialize]
    12.     public Dictionary<string, Dictionary<string, float>> FacialExpressionDictionary;
    13.  
    14.  
    15. CharacterRig characterRig;
    16.  
    17.     void Start()
    18.     {
    19.         characterRig = GetComponent<CharacterRig>();
    20.  
    21.     }
    22.  
    23.     public void SaveExpression ()
    24.     {
    25.         ExpressionName = FacialExpressionDictionary.Count.ToString();
    26.  
    27.  
    28.  
    29.  
    30.         FacialExpressionDictionary.Add (ExpressionName, new Dictionary<string, float>());
    31.  
    32.         FacialExpressionDictionary [ExpressionName].Add ("UpperEyeLidsPos", characterRig.UpperEyeLidsPos);
    33.         FacialExpressionDictionary [ExpressionName].Add ("LowerEyeLidsPos", characterRig.LowerEyeLidsPos);
    34.         FacialExpressionDictionary [ExpressionName].Add ("Squinch", characterRig.Squinch);
    35.         FacialExpressionDictionary [ExpressionName].Add ("Wrath", characterRig.Wrath);
    36.  
    37.  
    38.     }
    39.        
    40. }
     
  4. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,268
    Hello, I am trying to deserialize some data, and to do this I have a list of objects... serialization seems to work! (I saved it in JSON format, and it looks good to me) however, when I load this data, the list is full of empty objects...

    Also, does your serialization work polymorphism? I know Unity's serialization doesn't, unless it's a scriptable object, then it does....

    Thanks!
    Josh


    EDIT: Alright, it looks like Odin doesn't serialize ScriptableObjects? Interesting. Well, it works out for me, makes things less awkward actually, since I was only using ScriptableObjects since I needed polymorphism to work.

    It looks like polymorphism works? Is this correct?
     
    Last edited: May 20, 2018
  5. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    825
    Is there a way to disable odininspectors drawing of lists/arrays by default?
     
  6. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Ahh, sorry I was a bit too hasty with my first reply, didn't see that it was a Unity object you wanted to serialize. For that, you'll need to use the UnitySerializationUtility class instead. An important thing to understand here though is that Odin doesn't actually serialize the Unity objects themselves, it just serializes/deserializes all specified members of existing unity objects - which means that you'll have to give Odin a unity object to deserialize into.

    Here is an example. Hopefully, that makes sense.

    Code (CSharp):
    1. [Sirenix.OdinInspector.ShowOdinSerializedPropertiesInInspector]
    2. public class TestObject : ScriptableObject
    3. {
    4.     [SerializeField]
    5.     private Dictionary<string, string> test; // Odin will serialize this.
    6.  
    7.     [SerializeField]
    8.     private List<Object> referencedUnityObjects;
    9.  
    10.     [SerializeField]
    11.     private byte[] result;
    12.  
    13.     [Button(ButtonSizes.Large)]
    14.     public void Serialize()
    15.     {
    16.         bool serializeUnityFields = false;
    17.         UnitySerializationUtility.SerializeUnityObject(this, ref this.result, ref this.referencedUnityObjects, DataFormat.Binary, serializeUnityFields);
    18.     }
    19.  
    20.     [Button(ButtonSizes.Large)]
    21.     public void Deserialize()
    22.     {
    23.         UnitySerializationUtility.DeserializeUnityObject(this, ref this.result, ref this.referencedUnityObjects, DataFormat.Binary);
    24.     }
    25. }
    Another important thing to note is that Odin doesn't serialize all unity object references either, that's why it'll give you the referencedUnityObject list, which you'll need to store for it.

    If you're using SerializedMonoBehaviour / SerializedScriptableObject then things become a little more involved since it adds supports prefab modifications and a variety of different formats, - so you'll need to cast the object to
    ISupportsPrefabSerialization to get the serialziedData, use the UnitySerializationUtility.DeserializeUnityObject(unityObject, ref unityObject.serializationData) overload, and then manually figure out how to store the serializationdata.

    If you want to keep things simple, I would suggest you used ScriptableObjects for this - that way you avoid the hazzle of supporting prefab modifications, and you can keep things simple.
     
  7. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    That is just how Unity works, you would need to copy the component in play-mode and paste the values again when you exit play mode. Maybe consider storing the data in a scriptable object instead? Then the values won't reset since you're modifying the asset directly.
     
  8. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Yeah correct, polymorphism works!

    And while it's true that we don't serialize scriptable objects directly, we can serialize and deserialize everything they contain. And whenever we meet a unity object while serializing, we'll add it to a list of external references for Unity to serialize for us. We'll then use the same list again when deserializing.

    Maybe the answer I just gave to jsizemore answers some of your questions as well?
     
    joshcamas likes this.
  9. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Sure, throw this script in somewhere in your codebase, and most lists will be drawn with unity.

    Code (CSharp):
    1. [OdinDrawer]
    2. [DrawerPriority(0, 0, 2)]
    3. public class ListDrawer<TList, TElement> : OdinValueDrawer<TList>
    4.     where TList : IList<TElement>
    5. {
    6.     protected override void DrawPropertyLayout(IPropertyValueEntry<TList> entry, GUIContent label)
    7.     {
    8.         if (entry.Property.Info.SerializationBackend == SerializationBackend.Unity)
    9.         {
    10.             FieldInfo fieldInfo;
    11.             SerializedProperty unityProperty = entry.Property.Tree.GetUnityPropertyForPath(entry.Property.Path, out fieldInfo);
    12.             EditorGUILayout.PropertyField(unityProperty, true);
    13.         }
    14.         else
    15.         {
    16.             this.CallNextDrawer(label);
    17.         }
    18.     }
    19. }
    I wonder though, why do you want this? Would love the feedback :)
     
    thelebaron likes this.
  10. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Have you had a time to look into delayed field update handling?

    And on a related subject - is it possible to make OnValueChanged fire whenever Unity performs an undo on a given object? If it's not possible to detect what was exactly undone, making it impossible to fire OnValueChanged on a per-field basis, I'd appreciate a method attribute allowing me to handle that myself, something like ExecuteOnUndo you put on a custom method.

    One example of that would be a UI system where a value like density float can affect the construction of a 9-slice mesh or properties passed through a material property block. Undoing a slider change on a field like that should trigger an update of all dependent stuff. Previously I handled it all manually, but Odin makes handling direct field changes so easy that I can't help but hope for possibility of handling undo-triggered field changes through it. :)
     
  11. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    825
    To be honest Ive barely scratched odins usage, so mostly its to show things unity wouldnt by default and some other minor things here and there.
    That said the way it draws lists really jumps out on a readability point of view, where if I have a bunch of things that are just plain fields and then suddenly a big bright list, it always draws my eye no matter what I'm looking to inspect. The layout and functionality is great, but it would be nice to have an option for a less bright background color/value, more muted feel(imo).

    edit also getting an error in the script "Assets/Scripts/ListDrawer.cs(24,18): error CS1501: No overload for method `CallNextDrawer' takes `1' arguments"
     
    bjarkeck likes this.
  12. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    958
    Hi all,

    I am trying to create a custom Texture2D preview where it extracts each channel and display them in the editor.

    My approach was to use OnValueChanged attribute, but I ran into an issue which Unity thinks OnValueChanged attribute is undefined on my ScriptableObject.

    Odin does show it is applying to the object in Editor Types window, and the demo (which uses MonoBehaviour) doesn't have this issue.

    I have found an open issue related to this:

    https://bitbucket.org/sirenix/odin-inspector/issues/287/onvaluechanged-doesn-t-work-with

    - So does Odin support OnValueChanged in ScriptableObject?

    - If not, can you think of an alternative solution to my problem?

    Thx!
     
  13. dantonel

    dantonel

    Joined:
    Dec 7, 2015
    Posts:
    8
    I tried out the Beta. I like what I'm seeing so far (though I don't see the "CustomDeleteButton" property for ListDrawerSettings yet).

    As for the CreateNew that I want for list add buttons (or now, for value dropdown lists), could there be a version of ValueDropdownItem that takes a delegate instead of an item, and when the item is selected in the dropdown, it calls the delegate and puts the result into the list? That would let me do
    Code (CSharp):
    1. new ValueDropdownItem("Create New MyObject", () => (new GameObject()).AddComponent<MyObject>())
    and append/prepend that to my list of all existing MyObjects that I would use to populate the dropdown.
     
    bjarkeck likes this.
  14. cfusion

    cfusion

    Joined:
    Jul 18, 2011
    Posts:
    12
    Is it possible to use Odin to save a reference to a ScriptableObject inside a serializable class?

    For example, I have a ScriptableObject class called MyData. I also have a "save class":
    Code (CSharp):
    1. [System.Serializable]
    2. public class MySaveData
    3. {
    4.     [SerializeField]
    5.     private MyData _myData;
    6. }
    If I use Unity's JsonUtility to serialize MySaveData into json, it just serializes the instanceID of _myData.

    I could implement my own ID / look up table scheme to just save a string ID, and do a look up when I deserialize, but I don't want to over complicate things, and I also use the OdinEditorWindow to load and save json to make quick changes while I'm prototyping, so it's nice to be able to drag ScriptableObjects into the editor, save it off, then test the new data.
     
  15. jingray

    jingray

    Joined:
    Feb 6, 2015
    Posts:
    53
  16. dCalle

    dCalle

    Joined:
    Dec 16, 2013
    Posts:
    55
    Jesus... your tool is amazing... I got one question: How many people are working on Odin?
     
    bjarkeck likes this.
  17. Osteel

    Osteel

    Joined:
    Jan 17, 2014
    Posts:
    59
    Hi!

    I've been plagued with some sort of issue in my project. I haven't been able to resolve it and often had to revert commits just to go back to a stable state.

    Here's a gif of what is happening:
    https://imgur.com/a/iZsigkH

    When it occurs, while my mouse is over the window, I get these error messages:
    https://imgur.com/a/MMzKviM

    Here's is what the first part of the script in the gif looks like so:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Sirenix.OdinInspector;
    5. using System;
    6.  
    7. public class StorageManager : SerializedMonoBehaviour
    8. {
    9.     public static StorageManager instance;
    10.  
    11.  
    12.     // --- Storage --- //
    13.     [FoldoutGroup("Storage References")]
    14.     private List<Storage> storages = new List<Storage>();
    15.  
    16.     [FoldoutGroup("Storage References")]
    17.     private int equipmentStorageID;
    18.  
    19.     [FoldoutGroup("Storage References")]
    20.     private int backpackStorageID;
    21.  
    22.     // --- Debug --- //
    23.     [FoldoutGroup("Debug")]
    24.     private List<ItemDefinition> defaultItems = new List<ItemDefinition>();
    25.  
    26. }
    27.  
    It's been quite the blocker, so any help would be appreciated!
     
  18. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    974
    I'm using the very handy CustomContextMenu on an AnimationCurve to randomize it.

    Code (CSharp):
    1.     [CustomContextMenu("Randomize Curve", "RandomizeCurveWind")]
    2.     [ShowIf("IfWind")] [SerializeField] private AnimationCurve WindPattern;
    3.  
    4.     private void RandomizeCurveWind()
    5.     {
    6.         AnimationCurveExt.RandomizeCurve(ref WindPattern, 7, -.1f, .1f);
    7.     }

    The inspector doesn't refresh upon randomizing the curve however so I can't get a preview of the curve in the inspector unless I click on it. How can I force the refreshing of the inspector??
     
  19. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    First, sorry for the delay. It has been a busy week.

    Good catch. I've reproduced this with the PreviewField attribute, and it doesn't update the same way as the regular object field. Enums do have the same behaviour though, but we've also changed a bit in 1.1 so that might be why. I'll make sure all object pickers have the same behaviours as Unity's default. I'll have a look at it today, and see if I can get it into the next beta release. Would you be willing to participate in the beta and see if it works as expected? If so just give me a PM :)

    Also, do note that the OnValueChanged will only work when the value is modified directly from the inspector. If you want a more consistent OnValueChanged, consider hiding the field and property with a custom setter and showing that with [ShowInInspector].
     
  20. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Really appreciate the feedback. And I fully agree. In 1.1 we're also attempting to make Odin feel less boxy, by changing how the polymorphic object picker looks etc... It's an ongoing process though. We have plans to completely rewrite the list drawer soon with an improved one, and I'll definitely keep this in mind.

    Regarding the error, just call this.CallNextDrawer(entry, label); instead of this.CallNextDrawer(label);
     
    thelebaron likes this.
  21. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Right, answered you in there on the Bitbucket issue, thanks again for posting it.

    As an alternative solution, you could consider doing something like this, and show the channels with a custom shader?

    Code (CSharp):
    1. [OnInspectorGUI("DrawChannels")]
    2. public Texture2D test;
    3.  
    4. private void DrawChannels()
    5. {
    6.     var rect = EditorGUI.PrefixLabel(EditorGUILayout.GetControlRect(true, 50), new GUIContent(" "));
    7.     if (test)
    8.     {
    9.         Graphics.DrawTexture(rect.Split(0, 4), this.test, showRChannelMaterial);
    10.         Graphics.DrawTexture(rect.Split(1, 4), this.test, showGChannelMaterial);
    11.         Graphics.DrawTexture(rect.Split(2, 4), this.test, showBChannelMaterial);
    12.         Graphics.DrawTexture(rect.Split(3, 4), this.test, showAChannelMaterial);
    13.     }
    14. }
     
    bitinn likes this.
  22. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Ah sorry about that, the CustomDeleteFunction is on its way. Simply forgot to un-stash it. And good suggestion with the ValueDropdown being able to handle delegates! I will make it so that you if you return a ValueDropdownMenuItem that contains a Func<T> we'll just invoke that when selected. Can't promise it'll get in there in the next beta build but I'll try.
     
  23. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Thanks for the kind words! We're 3 persons actively working onit, and two companies involved with the project :) Sirenix and DevDog. DevDog helps us out marketing and publishing, and they are a two-man army.
     
  24. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    181
    This is possible, but only if you use Unity to store the Unity object references. Basically, what Odin does when it encounters serialized Unity object references is, it puts them into a list and references them by the index in the list. This list is then put into a Unity object to serialize and deserialize, since only Unity can handle such references in a robust manner. As such, you can only reference Unity objects in your serialized data when your serialization is happening in the context of another serialized Unity object. You cannot reference Unity objects in your serialized data if you want to store it yourself in a file that is not somehow saved by Unity as an asset. This is a fundamental limitation of how Unity does things, and there is categorically no general solution that is good - not unless Unity one day opens up the internals of their asset referencing system to the C# API.

    You can try playing around with Odin's SerializationUtility class, in particular the overloads of Serialize and Deserialize that take a List<UnityEngine.Object> as a parameter or create/populate one as a ref parameter - quite possibly it can help you resolve your difficulties.
     
  25. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    181
    I'm sorry to hear you've been having this issue. This issue has been fixed in Odin 1.1, which is currently in beta - the new patch uses an entirely different system from the old ObjectSelector. If you'd like to get in on the beta and give it a go, please send us your Odin invoice ID for confirmation, along with your mail, and we'll add you to the beta mailing list and send you the latest released beta build. You can send it by mail to contact@sirenix.net, via the contact form on our website, or head onto our discord and send it to one of us via PM.
     
  26. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    That is actually a limitation in Unity's AnimationCurve drawer which doesn't care about changes made from elsewhere. It's up to Unity to fix that. But yeah, you can trigger an inspector refresh with InspectorConfig.Instance.UpdateOdinEditors() It's not something that should be called every frame though, and it only refreshes the inspector window. So it doesn't work everywhere.
     
  27. jcox_PlayQ

    jcox_PlayQ

    Joined:
    Jun 22, 2016
    Posts:
    9
    Greetings!
    I'm wondering about load time effects of using Odin serialization. I had my company get Odin primarily for the inspector/editor customization to help us build tools for our artists and developers. It's been great for this and I'm thrilled with the package. However, the serialization portion of Odin has some really nice features that I would like to make use of too.
    The problem we're seeing is that simply having Odin serialization in our project increases load times unacceptably. For example, on our reference Pixel, including the serialization portion of the package increases load times by 1.5 seconds, which is a non-starter on mobile for us. This increase happens regardless of if we actually use any of the Odin serialization features. I have to put it in Editor-only mode for the load time increase to vanish.
    I'd like to use Odin serialization features at some point, so could you tell me if there are existing means to mitigate the load time effects or plans to optimize that issue in the future?

    Cheers!
    -j
     
  28. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    It's likely that we've already improved load-times in the latest beta version of Odin! In the version you have, we're scanning all types in all assemblies for serialization formatters, which is not the case en 1.1 beta. Instead, we've introduced an attribute which you need to define in the assembly to tell whether it contains any formatters. That way we'll only look in our own assembly for formatters in most cases.

    Would love if you would be willing to give the beta a run and see how much of an improvement it has given you? Would also love to experiment further if there is more that needs to be done about times. If you're up for it, send us a mail with your Odin invoice ID included from sirenix.net/contact
     
  29. jcox_PlayQ

    jcox_PlayQ

    Joined:
    Jun 22, 2016
    Posts:
    9
    Sure, will do.
    In the mean time, a follow up question: Is your anticipated workflow for users to isolate any custom formatters into their own library (marked with this new attribute of yours) so that having the attribute doesn't trigger the same full-game-code-assembly scanning?
     
  30. dantonel

    dantonel

    Joined:
    Dec 7, 2015
    Posts:
    8
    Awesome! Thanks!
     
  31. Caffeen

    Caffeen

    Joined:
    Dec 25, 2013
    Posts:
    34
    Hi! Is there a simple way to add a button to each element in a List<SomeClass>? I have a Drawer that displays each element of a list like so:


    I'd like to add an inline button that calls a method within the specific instance of each class. What's the simplest way to do this? Can I do it within the Drawer for <SomeClass>, or do I need to create a wrapper for the list and a drawer for that?

    Thanks for looking! I'm really loving Odin so far.
     
  32. hungrybelome

    hungrybelome

    Joined:
    Dec 31, 2014
    Posts:
    336
    @bjarkeck
    Hi, I'm having an issue that is blocking development. I renamed my main namespace for my game scripts from Foo to Bar, and now I get `Data layout mismatch` errors. I also tried replacing the old namespace in .asset files containing string names of scripts, which did not change anything. I also tried removing the assemblies and using the source scripts so that I could log which serialized asset/node is causing the issue, and I found out that the ExitNode() throws the error when called for the 'comparer' node, but when I look at the source for the problem serialized asset/node, I'm not sure what I can do to fix it.

    Here is the full stack trace:
    Code (CSharp):
    1. Data layout mismatch; skipping past array boundary when exiting node.
    2. UnityEngine.Debug:LogError(Object)
    3. Sirenix.Serialization.CustomLogger:LogError(String) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization.Config/CustomLogger.cs:53)
    4. Sirenix.Serialization.DebugContext:LogError(String) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Misc/SerializationConfig.cs:193)
    5. Sirenix.Serialization.BinaryDataReader:ExitNode() (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/DataReaderWriters/Binary/BinaryDataReader.cs:486)
    6. Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Serializers/ComplexTypeSerializer.cs:362)
    7. Sirenix.Serialization.DictionaryFormatter`2:DeserializeImplementation(Dictionary`2&, IDataReader) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Formatters/DictionaryFormatter.cs:70)
    8. Sirenix.Serialization.BaseFormatter`1:Deserialize(IDataReader) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Formatters/BaseFormatter.cs:172)
    9. Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Serializers/ComplexTypeSerializer.cs:332)
    10. Sirenix.Serialization.Serializer`1:ReadValueWeak(IDataReader) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Serializers/Serializer.cs:249)
    11. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, IDataReader) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Utilities/UnitySerializationUtility.cs:1433)
    12. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, Byte[]&, List`1&, DataFormat, DeserializationContext) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Utilities/UnitySerializationUtility.cs:1346)
    13. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext, Boolean, List`1) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Utilities/UnitySerializationUtility.cs:1079)
    14. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext) (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Utilities/UnitySerializationUtility.cs:994)
    15. Sirenix.OdinInspector.SerializedScriptableObject:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize() (at F:/Sirenix/Sirenix Solution/Sirenix.Serialization/Unity Integration/SerializedScriptableObject.cs:24)
    16. UnityEditor.BuildPlayerWindow:BuildPlayerAndRun()
    17.  
    Any idea on what is causing the issue? Are there specific steps that I need to take when renaming the namespace of a script that is being referenced by a serialized object? Maybe changing the string resulted in a different hashed guid, and the old hash wasn't replaced? Or maybe the different serialized asset byte size was cached somewhere, and the namespace string length change brough it out of sync with the cached length? Grasping at straws here, but trying to figure out how I can fix this.

    On OSX, Unity 2018.1.1f1, 1.0.6.8 (but just upgraded to 1.0.6.9 with no changes).

    Thanks

    *EDIT*
    Ended up fixing the `Data layout mismatch` errors by toggling the serialization mode in `Editor->Asset Serialization`, which will reserialize all assets.
     
    Last edited: Jun 9, 2018
  33. Deleted User

    Deleted User

    Guest

    Hi. I'm currently having hard time trying to use il2cpp compilation mode for android game.
    I have 2 two-dimentional arrays and a dictionary that I'm trying to serialize using Odin.

    Here is the log from android:

    Code (CSharp):
    1. NotSupportedException: C:\Program Files\Unity\Editor\Data\il2cpp\libil2cpp\icalls\mscorlib\System.Reflection.Emit\DynamicMethod.cpp(19) : Unsupported internal call for IL2CPP:DynamicMethod::create_dynamic_method - System.Reflection.Emit is not supported.
    2.  
    3.  
    4. Rethrow as Exception: Exception thrown while deserializing type 'Vajegoon.Data.Level': C:/Program Files/Unity/Editor/Data/il2cpp/libil2cpp/icalls/mscorlib/System.Reflection.Emit/DynamicMethod.cpp(19) : Unsupported internal call for IL2CPP:DynamicMethod::create_dynamic_method - System.Reflection.Emit is not supported.
    This is the Level script:
    Code (CSharp):
    1. /// <summary>
    2.     ///     Data Model of each level.
    3.     /// </summary>
    4.     public class Level : SerializedScriptableObject
    5.     {
    6.         [OdinSerialize] private TileType[][] tileTypes;
    7.         [OdinSerialize] private string[][] table;
    8.  
    9.         /// <summary>
    10.         ///     Gets or sets tile types of this level.
    11.         /// </summary>
    12.         public TileType[][] TileTypes
    13.         {
    14.             get { return tileTypes; }
    15.             set { tileTypes = value; }
    16.         }
    17.  
    18.         /// <summary>
    19.         ///     Gets or sets the characters of this level.
    20.         /// </summary>
    21.         public string[][] Table
    22.         {
    23.             get { return table; }
    24.             set { table = value; }
    25.         }
    26.     }

    This is what I have done but problem is still there. I scanned the project and hit the Generate DLL button. Then went for the build.

    aot.PNG
    Am I missing something?
     
  34. hungrybelome

    hungrybelome

    Joined:
    Dec 31, 2014
    Posts:
    336
    Have you done this:

    "If you want to build with IL2CPP then you currently need to manually ensure that the assemblies located in Assemblies/NoEditor (which uses Emit) are not targeting the platform you are building to, and likewise, ensure that the assemblies in Assemblies/NoEmitAndNoEditor are targeting the platform."
     
    Deleted User likes this.
  35. Deleted User

    Deleted User

    Guest

    Thank you! it's working now!

    I think this guide needs to be added added to the "AOT Generation" section in the Odin preferences for new people.
     
  36. dantone1

    dantone1

    Joined:
    Jun 2, 2017
    Posts:
    3
    Hi Odin Devs. Can you please include asmdef files (at the very least in all of your Editor folders) in your next release? I'm having issues with builds that are caused by Editor folders no longer being excluded from builds because of an asmdef file in my "include" or "plugin" folder that I put Odin inside of.
     
  37. doougles

    doougles

    Joined:
    Mar 30, 2015
    Posts:
    12
    Hi, just started playing around with Odin. Small question about if I'm using Horizontal Group correctly.

    Is there a reason the margins don't lineup for the two horizontal groups?

    upload_2018-6-9_16-22-18.png

    The class looks like this
    Code (CSharp):
    1. [Serializable]
    2.     public class EmitterData
    3.     {
    4.         public Ambience_Emitter emitter;
    5.  
    6.         [HorizontalGroup("Depth"), LabelText("Depth Range"), SuffixLabel("closest", true)]
    7.          public EmitterDepth closestDepth = EmitterDepth.Foreground;
    8.         [HorizontalGroup("Depth", MaxWidth = 0.33f), HideLabel, SuffixLabel("farthest", true)]
    9.          public EmitterDepth farthestDepth = EmitterDepth.Background;
    10.  
    11.         [HorizontalGroup("Pan"), LabelText("Pan Range"), SuffixLabel("left", true)]
    12.         [Tooltip("-1.0 is full left, +1.0 is full right")]
    13.          public float farthestPanLeft;
    14.         [HorizontalGroup("Pan", MaxWidth = 0.33f), HideLabel, SuffixLabel("right", true)]
    15.          public float farthestPanRight;
    16.  
    17.         [NonSerialized] public bool isStaticInThisScene = false;
    18.         [NonSerialized] public AreaType areaType;
    19.     }
     
  38. doougles

    doougles

    Joined:
    Mar 30, 2015
    Posts:
    12
    Also, the following seems to cause problems:
    Code (CSharp):
    1. [TitleGroup("PARAMETERS")]
    2.        
    3.         [NonSerialized] private float plantMaxVolumeInPercent;
    4.         public Band band = Band.Normal;
    Doing that actually renders plantMaxVolumeInPercent in the inspector!

    And if I use [Title] instead, the variable isn't exposed in the inspector, but the title never actually shows.

    If the non-NonSerialized variable goes first, everything works fine.

    Is this expected behavior? It took me a while to realize what was happening.
     
  39. Osteel

    Osteel

    Joined:
    Jan 17, 2014
    Posts:
    59

    Thank you for the beta - it did seem to fix my issue. However, it start happening again tonight. Just a quick summary of what's happening:

    Here's a gif of what is happening:
    https://imgur.com/a/iZsigkH

    When it occurs, while my mouse is over the window, I get these error messages:
    https://imgur.com/a/MMzKviM


    The set up is currently as follows:

    Code (CSharp):
    1. public class ActorController : SerializedMonoBehaviour
    2. {
    3. [SerializeField] private List<List<ScheduleDefinition>> schedules = new List<List<ScheduleDefinition>>();
    4.  
    5. }
    6.  
    7.  
    8. [CreateAssetMenu(menuName = "Definitions/Schedule")]
    9. public class ScheduleDefinition : ScriptableObject
    10. {
    11.     public DateStamp date;
    12.     public List<ScheduleEvent> events = new List<ScheduleEvent>();
    13. }

    I should note that this was working. But as before, it suddenly just breaks down without seemingly doing anything (no code changes or such).
     
  40. Aggressor

    Aggressor

    Joined:
    Aug 10, 2012
    Posts:
    62
    Can I make a feature request?

    If a dictionary already has a key, can you allow a "Replace" instead of just not allowing you to add dictionary. In large dictionaries it can be hard to find the key to replace it.
     
    dantonel likes this.
  41. dantone1

    dantone1

    Joined:
    Jun 2, 2017
    Posts:
    3
    This is likely caused by the fact that attributes (such as TitleGroup, in this case) *must* be tied to a field, property, method, class, etc. So even though you have TitleGroup a few lines up, it is *still* being applied to the private NonSerialized variable.

    So, yes, the behaviour you're seeing is odd, but also, you shouldn't be putting a private NonSerialized variable right after the TitleGroup attribute.
     
  42. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    I might be missing some attribute, but is it possible to do the following?

    • Make buttons appear before the fields
    • Separate buttons with a space attribute
     
  43. TomaszKozera

    TomaszKozera

    Joined:
    Oct 18, 2017
    Posts:
    14
    I'm having an issue with serialization of an array of arrays - it doesn't serializa and once in a while it gets cleared. This is something that Unity does not support but I got the impression that Odin should be able to do it?

    I have an public Action[][] actions; array, Action inherits from SerializedMonoBehaviour. Even if I use [OdinSerialize] attribute on the array it still will not be kept.

    Can you confirm or deny whether Odin is able to handle such a case?
     
  44. phulcyplayful

    phulcyplayful

    Joined:
    Jan 4, 2017
    Posts:
    1
    First I want to say I love your plugin! I have spent a LOT of time building various custom inspectors/property drawers and this plugin makes my life so much easier :)

    I am running into one issue however with the RangeAttribute.
    I have something like the following:

    Code (CSharp):
    1. [Range(0.0f, 40.0f)]
    2. [SerializeField]
    3. private float _floatRange;
    And it seems to be completely ignored by the Undo stack. Anytime I make a change to this value in the inspector and then try to Undo it reverses the change I made before changing the value with the RangeAttribute.

    For reference:
    Unity Version: 2017.3.0f3
    Odin Version: 1.0.6.9

    Thanks for any help you can provide!
     
  45. TomaszKozera

    TomaszKozera

    Joined:
    Oct 18, 2017
    Posts:
    14
    Getting back to my issue, I tried different approaches and it seems that none of them work.

    Something that should work was an attempt to create a list of objects that have a list inside them. Here's an example:
    Code (CSharp):
    1. public class MyData : SerializedMonoBehaviour
    2. {
    3.     ...
    4. }
    5.  
    6. public class ListHack : SerializedMonoBehaviour
    7. {
    8.     public List<MyData> list;
    9. }
    10.  
    11. public class OuterClass : SerializedMonoBehaviour
    12. {
    13.     public List<ListHack> realDataContainer;
    14. }
    15.  
    What should happen is that serialized object OuterClass has a serialized list of objects (ListHacks). Those objects are serializable and have a serialized list of serializable objects (MyData). So in theory it all should save properly. However, in practice once I set all the data in inspector, apply prefab and reload the scene, all the fields are nullified.

    Am I doing something wrong? I don't understand why it doesn't work...
     
  46. _Cartman_

    _Cartman_

    Joined:
    May 5, 2016
    Posts:
    6
    Hello.

    I’m using your asset Sirenix. It’s very good product, thank you for your work!

    The problem happens when I build empty project with only your plugin to WebGL. The result is managed code references to Collision, Physics and Rigidbody classes, and UnityEngine.PhysicsModule.dll puts in result build.

    Could you please explain, what part of your plugin is responsible for this fact? It’s very important for size of result build.

    Thank you
     
  47. MacFBG

    MacFBG

    Joined:
    Jan 23, 2016
    Posts:
    18
    Hey folks,

    Really enjoying the tool. I have ran into a problem though. We're using the ValueDropDownList to display a bunch of character stats. We currently have 1300 of them, unfortunately there seems to be a limit on the amount of items that the ValueDropDownList can display, it currently cuts off after 1159.

    Is this a limitation with Odin? Is there any way to override the maximum number of items?
     
  48. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    winterkewl likes this.
  49. Naberius

    Naberius

    Joined:
    May 16, 2015
    Posts:
    4
    Hello, all
    I'm trying to implement the DeserializeValue method as a drop-in replacement for BinaryFormatter Deserialize and I've run into something of a snag. When attempting to load the data, I get an odd error:

    Invalid binary data stream: could not parse peeked BinaryEntryType byte '0' into a known entry type

    Am I missing something here?

    List of Details
    1. Data was serialized using BinaryFormatter Serialize
    2. Data is a struct with arrays of structs using simple data types (that conform to BinaryFormatter's requirements)
    3. Data is being stored in a TextAsset and being read from the .bytes prop
    4. My implementation looks like...

    Code (CSharp):
    1. // Odin deserialisation
    2. dataToLoad = SerializationUtility.DeserializeValue<ReplayData>(bytes, DataFormat.Binary);
    3. // binary formatter deserialisation
    4. /*
    5. Stream s = new MemoryStream(bytes);
    6. BinaryFormatter bf = new BinaryFormatter();
    7. dataToLoad = (ReplayData)bf.Deserialize(s);
    8. */
     
  50. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    I have a class that must derive from GridBrushEditor to override methods like PaintPreview even though I am not changing or using the OnGUI in any way.

    In that case the Inline attribute does not work, and the reorderable lists do not work, and nothing works...

    Is there some attribute or something that could make it work in this situation? Or something I can write in my OnGUI to make Odin work in this situation?

    Thank you :)

    Edit: I imagine there is a DrawDefaukOdintInspectkr or something
     
    Last edited: Jun 29, 2018
    untory likes this.