Search Unity

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

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

  1. dantonel

    dantonel

    Joined:
    Dec 7, 2015
    Posts:
    8
    Sweet. Thanks!
     
  2. fidelsoto

    fidelsoto

    Joined:
    Aug 7, 2012
    Posts:
    87
    Hello, I'm new to Odin, loving it so far!
    Question:

    I have this:
    InfoSequence.png

    using System;
    using System.Collections.Generic;
    using UnityEngine;
    using Sirenix.OdinInspector;

    namespace OkusInfo
    {
    public enum PetTransition
    {
    FadeIn,
    FadeOut,
    Minimize,
    Maximize
    }

    public class InfoSequence : SerializedMonoBehaviour
    {
    [HideReferenceObjectPicker]
    public List<Info> sequence;
    }

    public class Info
    {
    [PropertyOrder(2)]
    public bool pause;
    }

    public class Dialogue : Info
    {
    [TextArea]
    public string dialogue;
    }

    public class AnimationStep : Info
    {
    public Animator animator;
    }

    public class PetAction : Info
    {
    public PetTransition action;
    }
    }


    I want this:
    InfoSequenceWhatIWant.png

    I want add buttons on every element of the list. They should add a new instance of the class (should let me pick the class type) directly below the element I clicked. Also the add button on top should add a new element at the very top of the list instead of at the bottom.

    Is this possible?

    Also, can I hide the base class from the add new class instance class type picker?

    Edit:
    I know editor scripting. So I guess my question is: How do I combine editor scripting with Odin's serialization behavior for polymorphic lists?
     
    Last edited: Mar 24, 2018
  3. dantonel

    dantonel

    Joined:
    Dec 7, 2015
    Posts:
    8
    Is there an easy way to customize what happen when the "delete" button is clicked on a List item? There doesn't seem to be a straightforward way like there is for the CustomAddFunction.

    ( edit: )
    I could also see using OnEndListElementGUI in the ListDrawerSettingsAttribute, but I would still need to get rid of the existing "x" button, right?
     
    Last edited: Mar 23, 2018
  4. greengremline

    greengremline

    Joined:
    Sep 16, 2015
    Posts:
    183
    Hey just purchased your asset, I've been able to remove a lot of my custom code I wrote for dealing with lists of scriptable objects! I'm really liking the list, but I have a question - say I have a ScriptableObject that has a list of other ScriptableObjects (a PickupDatabase with a list of pickups). I need a way to add a new ScriptableObject when clicking the plus button, is there a way to override the default behavior so that it calls my own function instead - to open up an add new window?
    upload_2018-3-24_15-39-16.png

    Thanks so much!
     
    bjarkeck likes this.
  5. fidelsoto

    fidelsoto

    Joined:
    Aug 7, 2012
    Posts:
    87
    I believe this case is covered in the documentation here:
    http://sirenix.net/odininspector/documentation/sirenix/odininspector/listdrawersettingsattribute
     
    bjarkeck likes this.
  6. fidelsoto

    fidelsoto

    Joined:
    Aug 7, 2012
    Posts:
    87
    I think I found my answer here:
    Next time I buy an asset I will read the documentation AND the forum before asking a question.

    Looks like its in the FAQ as well:
    http://www.sirenix.net/odininspector/faq/13/can-i-use-odin-inspector-to-create-custom-editor-windows

    Edit:
    I did exactly whats in the FAQ (see code below) for my polymorphic list and the editor slows down to a crawl when I inspect the object.

    Code (csharp):
    1.  
    2. [CustomEditor(typeof(MyMonoBehaviour))]
    3. public class CustomOdinEditor : OdinEditor
    4. {
    5.    public override void OnInspectorGUI()
    6.    {
    7.        var tree = this.Tree;                                      // Like this.serializedObject.
    8.        var obj = this.target as MyMonoBehaviour;
    9.  
    10.        InspectorUtilities.BeginDrawPropertyTree(tree, true);      // This and EndDrawPropertyTree automatically handles a lot of stuff like prefab instance modifications and undo
    11.  
    12.        var someProp1 = tree.GetPropertyAtPath("someProp1");   // Like serializedObject.FindProperty("path")
    13.        someProp1.Draw();                                      // Like EditorGUILayout.PropertyField(property);
    14.  
    15.        InspectorUtilities.EndDrawPropertyTree(tree);
    16.  
    17.        // You can also call base.OnInspectorGUI(); instead if you simply want to prepend or append GUI to the editor.
    18.    }
    19. }
    20.  
     
    Last edited: Mar 26, 2018
  7. Deleted User

    Deleted User

    Guest

    Really great asset!
    I have two questions though, First, is it possible to automatically serialize all auto-properties in classes without placing OdinSerialize attribute on each one of properties?
    Second, Is it possible to use Odin serialization to serialize and deserialize entire scene in runtime?
     
    bjarkeck likes this.
  8. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    It's possible to add your own custom serialization policies using the ISerializationPolicy, but we don't have any guide on doing that, so you would need to dig through the code, starting at SerializedMonoBehaviour and see how it could be achieved.

    However, I would advise against serializing properties, for a number of reasons:

    You can only safely serialize auto-properties. But full property full property implementations can't safely be called directly during serialization, as they can easily execute code that is not allowed are meant to be called during when that happens. Furthermore, virtual properties, (this includes all properties declared by interfaces), might be an auto-property in one class. But nothing is to say, that another class can't override that implementation, and ruin the serialization. Also, should you ever convert an auto-property to a full property implementation, you would have to use the [FormalySerializedAs] on the backing field etc, which one might forget resulting in loss of data.

    Having a full property implementation with a serialized backing field is much more robust, and more clear in terms of data. And it also allows you to rename the property without worrying about a thing :)

    You can use Odin's serialization during runtime to both serialize and deserialize custom data. But you can't serialize any Unity objects down directly as assets during runtime out of the box. That requires Unity to serialize it, which is only possible in the editor. Only Unity can serialize Unity objects. In fact, whenever Odin encounter a UnityObject, it gets stored in a separate list, which we then let Unity handle for us.
     
    Last edited: Apr 23, 2018
    Deleted User likes this.
  9. fidelsoto

    fidelsoto

    Joined:
    Aug 7, 2012
    Posts:
    87
    So why is this so slow?

    Code (csharp):
    1.  
    2. using UnityEditor;
    3. using Sirenix.OdinInspector.Editor;
    4.  
    5. [CustomEditor(typeof(DerivedList))]
    6. public class CustomOdinEditor : OdinEditor
    7. {
    8.     public override void OnInspectorGUI()
    9.     {
    10.         var tree = this.Tree;                                      // Like this.serializedObject.
    11.         var obj = this.target as DerivedList;
    12.  
    13.         InspectorUtilities.BeginDrawPropertyTree(tree, true);      // This and EndDrawPropertyTree automatically handles a lot of stuff like prefab instance modifications and undo
    14.  
    15.         var someProp1 = tree.GetPropertyAtPath("instance");   // Like serializedObject.FindProperty("path")
    16.         someProp1.Draw();                                      // Like EditorGUILayout.PropertyField(property);
    17.  
    18.         InspectorUtilities.EndDrawPropertyTree(tree);
    19.  
    20.         // You can also call base.OnInspectorGUI(); instead if you simply want to prepend or append GUI to the editor.
    21.     }
    22. }
    Code (csharp):
    1.  
    2. using Sirenix.OdinInspector;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class DerivedList : SerializedMonoBehaviour {
    7.  
    8.     [HideReferenceObjectPicker]
    9.     [ListDrawerSettings(ShowPaging = false)]
    10.     public List<BaseClass> instance;
    11. }
    12.  
    13. public class BaseClass
    14. {
    15.     [PropertyOrder(2)]
    16.     public bool booleanVariable;
    17. }
    18.  
    19. public class DerivedClass1 : BaseClass
    20. {
    21.     public float floatValue;
    22. }
    23.  
    24. public class DerivedClass2 : BaseClass
    25. {
    26.     public string stringValue;
    27. }
    28.  
    29. public class DerivedClass3 : BaseClass
    30. {
    31.     public Animator animatorReference;
    32. }
    33.  
    Edit: Actually seems like whats broken is collapsing the list (animated) only. It goes slow and stops midway.
    Also the vertical top position a bit off.
    derivedlist.png
    Adding EditorGUILayout.Space(); on top fixed this, but I'm still wondering why the folding is so slow. I set the foldout animation time to 0.001 for now.
     
    Last edited: Mar 26, 2018
  10. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    You could also create a custom drawer for that. Here is something to get you started :)

    Code (CSharp):
    1.  
    2. [OdinDrawer]
    3. [DrawerPriority(DrawerPriorityLevel.WrapperPriority)]
    4. public class ListElementDrawer<T> : OdinValueDrawer<T>
    5.     where T : Info
    6. {
    7.     protected override void DrawPropertyLayout(IPropertyValueEntry<T> entry, GUIContent label)
    8.     {
    9.         if (entry.ValueCategory == PropertyValueCategory.StrongListElement)
    10.         {
    11.             var objectPicker = ObjectPicker<Info>.GetObjectPicker(entry);
    12.             if (GUILayout.Button("+"))
    13.             {
    14.                 objectPicker.ShowObjectPicker(false, entry.Property.LastDrawnValueRect, false);
    15.             }
    16.             if (objectPicker.IsReadyToClaim)
    17.             {
    18.                 var value = objectPicker.ClaimObject();
    19.                 object[] values = new object[entry.ValueCount];
    20.                 values[0] = value;
    21.                 for (int j = 1; j < values.Length; j++)
    22.                 {
    23.                     values[j] = SerializationUtility.CreateCopy(value);
    24.                 }
    25.                 var listChanger = entry.Property.FindParent(PropertyValueCategory.Member, false)
    26.                     .ValueEntry.GetListValueEntryChanger();
    27.                 listChanger.InsertListElementAt(entry.Property.Index, values, "List element inserted");
    28.             }
    29.             this.CallNextDrawer(entry, label);
    30.         }
    31.         else
    32.         {
    33.             this.CallNextDrawer(entry, label);
    34.         }
    35.     }
    36. }
    37.  
     
    fidelsoto likes this.
  11. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    It seems slow because it's not repainting. Just add this.RepaintIfRequested(); at the bottom of the OnInspectorGUI
     
    wzq19970428 and fidelsoto like this.
  12. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    Are there any tips for performance anywhere?

    I'm new to Odin, and really only want to use it to be able to show dictionaries in the inspector for now. The nicer lists are an added bonus, but I can deal with the default drawing of them. The performance I'm getting isn't great though.

    I created a simple test to try and narrow down if it was a specific type of collection that was causing issues. I have one SerializedMonoBehaviour with an int[4096]. When clicking the object to view it in the inspector while the game is running framerate drops from 60fps to 20fps.

    Any tips?

    Edit: Further testing shows that the default unity drawer slows down a ton in the same situation. Guess I can just be more careful of what I'm showing in the inspector, and just hide lists unless I really need to see them.

    Surprisingly, marking my int[4096] array with [HideInPlayMode] removes it from the inspector in play mode, but doesn't change the framerate. Using the built-in [HideInInspector] does, but means I can't edit the values during edit time without editing the script file >.<
     
    Last edited: Mar 26, 2018
  13. hungrybelome

    hungrybelome

    Joined:
    Dec 31, 2014
    Posts:
    336
    Just wanted to mention that this is no longer an issue for me with 1.0.6.1!
     
    bjarkeck likes this.
  14. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Performance issues will be adressed in our next major patch 1.1 which we'll start beta testing of very soon! From our patch-notes: http://sirenix.net/odininspector/releasenotes/1-0-6-1

    The best thing you can do until then, is to disable Odin for those types that contain a lot of data.
     
    DMeville likes this.
  15. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Is there an ETA on 1.1 :) ?
     
  16. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Soon :p

    Send us an email from sirenix.net/contact with your Odin invoice Id if you want in on an early beta :)
     
    BTStone likes this.
  17. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    EDIT: Silly me, Unity 5.6+ has uint serialization support. So my main issue is a non-issue really.

    But do let me know if Odin can now be used in more modular fashion, loved its inspector upgrade :)

    ----

    Hi All,

    I bought Odin a long time ago and was planning to use it, but then went for some lighter and modular solutions (like a custom serializable dictionary, or a custom reorderable list, etc., instead of depending on a custom monobehaviour).

    Now I am facing another data structure I want to serialize, specifically, uint, which I will use as List<uint> and SerializableDictionary<uint, T>.

    I realize my previous approach isn't very sustainable, as I am just reinventing the wheel here by creating serializable class and custom inspector Odin has already done.

    So I am thinking of switching back to Odin, but I would like to do it in a modular way if it's possible.

    I wonder if I can use Odin's uint32serializer in a low impact way? Like, allow me to declare a custom serializable uint type and define a custom inspector (see the custom dictionary mentioned above).

    I know Odin's binary serialization is wired quite deeply so I am not sure what I can do...
     
    Last edited: Mar 30, 2018
    bjarkeck likes this.
  18. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Good to hear you found a solution :) If not, Odin would definitely also have alternative options for you. You can easily use Odin Inspector for only the inspector upgrades btw. Odin's inspector upgrades doesn't require you to inherit from any specialized MonoBehaviour. They just work out of the box.

    231befc2-0b39-4e8a-a955-2abd934e55bf_scaled.jpg
     
  19. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    @bjarkeck Do you know if there is a way to use SirenixEditorFields to show UnityEvents and UnityActions?
     
  20. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Afraid not. As far as I'm aware the only way of drawing it is through Unity's SerializedObject and SerializedProperties.
     
  21. jay-jin

    jay-jin

    Joined:
    Jun 22, 2014
    Posts:
    12
    Hi, I have an idea that I wish to be adopted. I hope to be able to make my own timeline in editorWindows. But my attempt is not ideal, perhaps you can give some advice or provide a timeline in editorWindows?
     
  22. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,277
    Hello, I have a custom drawer that I'm wanting to use [UseInlineEditor] on.

    Basically, I have a value inside the property that I want to draw an inline editor for :)

    Is this possible?
     
  23. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Trying to figure out how to do something can someone type me out a example. My csharp is so so. so the documentation is confusing a bit for me :(

    Code (csharp):
    1.  
    2.     [ValueDropdown("IdleAnimationType")]
    3.     public int m_IdleAnimationType;
    4.  
    5.     private ValueDropdownList<int> IdleAnimationType = new ValueDropdownList<int>(){
    6.         {"Default",0},
    7.         {"Human",5},
    8.         {"Raptor",3},
    9.     };
    10.  

    Lets say Human is selected in the inspector.
    How can I return Human as a string. I can get the int value just by reading the variable m_IdleanimationType.
    Keep in mind int values can be the same.
     
    Last edited: Apr 2, 2018
  24. Froghuto

    Froghuto

    Joined:
    Oct 4, 2012
    Posts:
    61
    Is it possible to get a [ValueDropdown] on the key of a dictionary somehow?
     
  25. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Froghuto likes this.
  26. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Not entirely sure I got your question right but is this what you're looking for?

    Code (CSharp):
    1. string name = IdleAnimationType[m_IdleAnimationType].Text
     
  27. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Sounds like something that is possible :) If you could share the code then it'll be easier for me to help you figure out how. (drawer + the class containing the field you want the inline editor for)
     
    joshcamas likes this.
  28. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,277
    Alright, so I have a class called "ScriptableObjectParameter". It has a variable called "value", which is a scriptable object.

    I want to be able to put an attribute onto the class, but apply it to a value in the class itself... sounds confusing, I know. :/

    So:

    [UseInlineEditor]
    public ScriptableObjectParameter param;

    Would make a specific variable inside the class have inline editor enabled.

    Is there a way to do this? I'd be insanely useful if I could make it so all or specific attributes could basically be pointed to a certain value (For me, it's just a scriptableobject variable named "value").

    In other words, ScriptableObjectParameter is a sort of container for a value, with some special get and set logic and stuff
     
  29. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,940
    @bjarkeck
    Hi there, i have a generic monobehaviour based class like this
    Code (CSharp):
    1. public MyDataProvider<VOItem> : MonoBehaviour
    2. where VOItem:object{
    3.  
    4. }

    and i use it in control generic class
    Code (CSharp):
    1. public MyControl<VOItem> : MonoBehaviour
    2. where VOItem:object{
    3.  
    4. public MyDataProvider<VOItem> dataProvider;
    5.  
    6. Start(){
    7.  
    8. dataProvider = GetComponent<MyDataProvider<VOItem>>();
    9.  
    10. }
    11.  
    12.  
    13. }
    and finally a concrete implementation of both control and data provider. Currently i have to attach both concrete dataprovider and concrete control to the gameobject . and it works.


    But now i want to use same dataProvider class to 2 different gameobjects, and i want to do that "visually" dragging and dropping the concret dp class to that generic dataProvider property. Is there any attribute for that in Odin which exposes it to editor?


    Thanks
     
  30. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,940
    Update 2:
    I'm able to show this field in insepctor using [ShowInInsepctor] and able to drag the shared dataprovider, however when i run the app it loses the references. What should i do?
     
  31. xjjon

    xjjon

    Joined:
    Apr 15, 2016
    Posts:
    612
    Just a note about one of the sample projects (RPG Editor)

    Code (CSharp):
    1.  // If you inspect the Character Overview in the inspector, you will also notice, that
    2. // the list is not directly modifiable. Instead, we've customized it so it contains a
    3. // refresh button, that scans the project and automatically populates the list.
    However - it is mutable, as the elements are mutable.

    Code (CSharp):
    1. [ReadOnly]
    2. [ListDrawerSettings(Expanded = true)]
    3. public Character[] AllCharacters;
     
  32. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    Is there an option to change the background color or put horizontal lines between list elements? When you have a list of a struct, it is currently not easy to see where one element ends and the next begins without looking very closely at it.
     
  33. SamuelAsherRivello

    SamuelAsherRivello

    Joined:
    Jan 16, 2011
    Posts:
    41
    I downloaded the latest version of Odin 1.0.6.4.

    In 2017.1 and above it works great.

    In 5.6.2p2 the console is spammed with this error. Please fix.

    MissingMethodException: Method not found: 'UnityEngine.Debug.get_unityLogger'.
     
  34. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Thanks, will look into it. Could you post the full log of that message? Or was that all it said? Were the other messages as well? Did it happen only in a certain scene? Some more information would be useful.
     
  35. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Finally I have the time to play around with this impressive tool. I downloaded the latest version in a clean new Unity project (using the very latest Unity 2017.4.0f1 on MacOS). I imported all the Demo Scenes and Scripts.

    Looking into the "Odin Attributes Overview", selected the "Default Drawer Changes" object and when I the "Normal Enum" field, which is set to the value "M" a window pop ups which just displays nothing along with a Console Warning, saying:



    Could not get serialized property for type EnumSelector<KeyCode>; this type will not be shown in the inspector.
    UnityEngine.Debug:LogWarning(Object)
    Sirenix.OdinInspector.Editor.InspectorPropertyInfo:populateUnityProperties(Type, List`1) (at D:/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Utilities/SerializationDebugger/SerializationInfoMenuItem.cs:45)
    Sirenix.OdinInspector.Editor.InspectorPropertyInfo:CreateInspectorProperties(Type, Boolean) (at D:/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Utilities/SerializationDebugger/MemberSerializationInfo.cs:30)
    Sirenix.OdinInspector.Editor.InspectorPropertyInfo:Get(Type, Boolean) (at D:/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Utilities/SerializationDebugger/MemberSerializationInfo.cs:21)
    Sirenix.OdinInspector.Editor.PropertyTree`1:.ctor(EnumSelector`1[], SerializedObject)
    System.Activator:CreateInstance(Type, Object[])
    Sirenix.OdinInspector.Editor.PropertyTree:Create(IList, SerializedObject) (at D:/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Attribute Drawers/InlineEditorAttributeDrawer.cs:381)
    Sirenix.OdinInspector.Editor.PropertyTree:Create(IList)
    Sirenix.OdinInspector.Editor.PropertyTree:Create(Object)
    Sirenix.OdinInspector.Editor.OdinEditorWindow:UpdateEditors() (at D:/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/Children/PropertyValueCollection.cs:146)
    Sirenix.OdinInspector.Editor.OdinEditorWindow:OnGUI() (at D:/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/Children/PropertyValueCollection.cs:141)
    UnityEngine.GUIUtility:processEvent(Int32, IntPtr)

    EDIT:
    Happens with Flag Enums, too!


    I attached a screenshot and marked the empty Window in the upper left.
     

    Attached Files:

    bjarkeck likes this.
  36. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Thanks for the report and help on Discord.

    To everyone:
    We've accidentally introduced a bug in the latest 1.0.6.5 patch that got approved yesterday on the Asset Store. The bug affects all Unix based operating systems, and causes a wide range of strange behaviour. If you're on Windows you're good, but if not, best wait for the patch 1.0.6.6 to upgrade. So sorry about this! The hotfix 1.0.6.6 is already on its way to the Asset Store, but for those affected and need it now, just send us a message on discord, mail, or from our website with your Odin invoice number included, and we'll send you the hotfix right away.
     
  37. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    Hi @jorisshh @bjarkeck

    I am using Odin Inspector which seems very nice so far.

    What is the best (easy, readable, and reliable) way to represent/visualize JSON data in Odin-enabled editor inspector (or in other editor windows)?

    I imagine a JSON-message-receiving scenario like these steps below.
    (1) Use BestHTTP to receive a JSON message from a remote server;
    (2) Use JSON.NET to convert the JSON message (string) to a C# dictionary object;
    (3) Use SerializedMonoBehaviour of Odin to represent the C# dictionary object on an inspector.

    Is there any other better solution compared to the solution above?

    It seems Odin has both binary and JSON serializers. However, Odin typically uses its binary serializer. Right?
    Since general JSON serializer is not Odin's main focus, I should avoid using it in this scenario? Odin's JSON serializer is not for general usage scenarios like encoding or decoding HTTP JSON messages?
     
  38. Wawro01

    Wawro01

    Joined:
    Apr 23, 2014
    Posts:
    44
    Hi all, Is there a way to create something like Foldable Title ? IE to have possibility to fold multiple properties without having attributes for all those properties like it is in FoldableGroup?
     
  39. Aggressor

    Aggressor

    Joined:
    Aug 10, 2012
    Posts:
    62
    Hello!

    I have a question about serialization.

    I have a dictionary that is serialized and working fine. It lets me add objects with an interface to it and all works well:

    Code (CSharp):
    1.     [SerializeField]
    2.     Dictionary<T_Effects, IResolver> _resolvers; // Appears in inspector
    And it shows up just fine in the inspector and lets me add objects to it:

    odin1.png

    However, if I tried to serialize just a regular field of that IResolver type it is not appearing in the inspector:

    Code (CSharp):
    1.     [OdinSerialize]
    2.     private IResolver _resolver; // Not appearing in inspector
    Do you know why it lets me create a new instance of this in the dictionary just fine (as above) but it's not letting me serialize just a regular variable of it and have it appear in the inspector
     
    Last edited: Apr 24, 2018
  40. Curwen

    Curwen

    Joined:
    Jan 12, 2015
    Posts:
    13
    Hi,

    I'm failing to get a list of a particular class derived from SerializedMonoBehaviour to show inline editors for its items.

    If I create a class to contain the list such as:

    Code (CSharp):
    1. public class ClassA : SerializedMonoBehaviour
    2. {
    3.     public List<ClassB> myList;
    4. }
    and one to be contained in the list like this:

    Code (CSharp):
    1. public class ClassB : SerializedMonoBehaviour
    2. {
    3.     public float someFloat;
    4. }
    I couldn't find a way to get the list to automatically show the inline editor and expose someFloat for each of its items.

    Am I missing something or is that not supported?

    I can wrap ClassB in ClassC:

    Code (CSharp):
    1. public class ClassC
    2. {
    3.     [InlineEditor]
    4.     public ClassB classB;
    5. }
    and change ClassA to:

    Code (CSharp):
    1. public class ClassA : SerializedMonoBehaviour
    2. {
    3.     public List<ClassC> myList;
    4. }
    but that's cumbersome and I'm wondering if it's possible without that trick.
    Is there an alternative to the [InlineEditor] attribute for Lists? Or an attribute I must use on ClassB to make it use the inline editor when used in a list?


    Thanks!

    EDIT: In this particular case I realized I didn't actually really need ClassB to be a monobehaviour at all, so making it a simple class works for now. Still interested in whether there's a trick for exposing the editors of referenced monobehaviours as list items.
     
    Last edited: Apr 25, 2018
  41. Cynikal

    Cynikal

    Joined:
    Oct 29, 2012
    Posts:
    122
    Just tried to use this in 2018.2.0b2, a TON of errors. Windows blank.
     
  42. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    What issues might occur if one are to use:

    [OdinSerialize, SerializeField]
    private MyCustomClass MyClass = null;

    In other words, what can happen if Odin AND Unity serialize the same object? I've read that one can use NonSerialized, but I can see nowhere what (can) happen if both actually serialize it.

    I'm coming from FullInspector and I'm scared to be too dependent on any Serializer/Inspector. I want to avoid needing Odin in my Model-classes, but at the same time I want some customization. :)

    Thanks!
     
  43. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Exactly, the JSON serializer is mostly just there to present a readable serialization format for Odin. It's great for debugging etc, but it still requires the data to both be serialized and deserialized by Odin, and if you're doing that, there's not a big reason to not just use the binary formatter.

    Beyond that, if you only need to display the data using Odin, and you're using JSON.NET to handle the data, then you don't actually need to inherit from SerializedMonoBehaviour etc.. You can just put [ShowInInspector] on the things you would like Odin to display.
     
  44. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Well either put all the properties in a class or a struct, or put a [FoldoutGroup] on each of the members you would like in to be foldable. Sorry if I have misunderstood your question, I'm a little in doubt about what the difference would be between a FoldableTitle and FoldoutGroup attribute, besides the visual style?
     
  45. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Hey there, I would recommend you fired up the Serialization Debugger found in "Tools -> Odin Inspector -> Serialization Debugger" And if that's not able to answer your question, then maybe this FAQ can help.

    http://www.sirenix.net/odininspecto...t-serializing-or-showing-my-field-or-property

    And if non of that worked, then please share all of the code involved, all the way from the SerializedMonoBehaviour / SerializedScriptableObject, that way I can more easily see what's going on.
     
  46. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Good to hear you found a solution. The alternative would be to Also, be careful about inheriting from SerializedMonoBehaviour. Only do that, if you know you need to:) Throw a [Serializable] attribute on top of ClassC, and let Unity serialize it. Most of the time Unity should serialize your values, not Odin.

    To answer your original question, if you have a list of unity objects, putting the [InlineEditor] attribute on the list itself, would work as well.
     
  47. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Hey, we have fixed the errors for the latest beta-version, and we'll be submitting that to the Asset Store soon. But until then, feel free to send us an email with your Odin invoice Id, included, and then well send you the hotfix right away.
     
  48. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Good question, and the answer is quite simple :)

    If both Unity and Odin serializes the that field, then the first thing that will happen is that Unity will see the null value, and automatically populate it with an instance of MyCustomClass, this happens in Unity's deserialization as well as serialization. If it wasn't serialized by Unity, then it would remain null, and show up as null in the inspector.

    When you serialize it, then first Unity will serialize it, then Odin.
    And when you deserialize it, then Unity will deserialize first, and then Odin.

    And I agree - stick with Unity's serialization where ever you can, and only use Odin to serialize those fields Unity can't. Odin will automatically detect these, so if you have a SerializedMonoBehaviour, Odin will skip all those fields that Unity is already serializing. Unless you explicitly told Odin to as in your example above.
     
  49. Aggressor

    Aggressor

    Joined:
    Aug 10, 2012
    Posts:
    62

    So IResolver is just an interface with 3 methods. For some reason (and this is what Im curious about), the default behaviour of the dictionary is to instantiate the object from the inspector and add it to the dictionary. I want to do this same behaviour for just a variable. odin1.png


    However when I try doing it with just a IResolver variable, nothing appears (there is no code to be serialized its just an interface with methods). I would like to store an instantiated reference to a local variable as the default behaviour does for the dictionary.

    If there is more info I can provide please ask, because as far as I can tell this is just the default behaviour for the dictionary but its not working for a plain old variable.
     
    Last edited: Apr 27, 2018
  50. adamzl

    adamzl

    Joined:
    Feb 24, 2018
    Posts:
    19
    Has anyone found a way to combine the two attributes [AssetList] and [TableMatrix]? My hope is to have an autopopulating list of assets and then render it as a table matrix.

    The major issue I cannot seem to solve is that AssetList is for single-dimension arrays and TableMatrix is for double-dimension arrays. Simply adding both attributes to one field gives an error indicating such. I've been trying to use [OnInspectorGUI] to copy from an AssetList to a TableMatrix but OnInspectorGUI seems to execute before the AssetList is populated, length zero.

    All I really want to do is make a two-dimensional array of Prefabs with the preview boxes.