Search Unity

Assets [WIP] Odin Inspector & Serializer Looking for Feedback

Discussion in 'Works In Progress - Archive' started by jorisshh, Feb 22, 2017.

  1. SuneT

    SuneT

    Joined:
    Feb 29, 2016
    Posts:
    41
    The latest version of Odin is out, and here's the changelog :)

    Odin Inspector & Serializer v. 1.0.4.0 + 1.0.4.1 changelog
    Upgrade notes for 1.0.4.0:

    • Delete the Sirenix/Demos folder before upgrading, as we have deleted a demo script that is now obsolete.
    Highlights:
    • Added a new attribute called InlineProperty which can be applied to classes, structs and members. Instead of drawing the value in a foldout, Odin will draw the label to the left and its inner content to the right.
    • Added a new attribute Called LabelWidth which changes the width of the label.
    • Deprecated the ShowForPrefabOnly and EnableForPrefabOnly attributes and added 8 new prefab related attributes which gives you much more control.
      • Added a new attribute called DisableInPrefabs which disables a property if it is drawn from a prefab asset or a prefab instance.
      • Added a new attribute called HideInPrefabs which hides a property if it is drawn from a prefab instance or a prefab asset.
      • Added a new attribute called HideInPrefabInstances which hides a property if it is drawn from a prefab instance.
      • Added a new attribute called HideInPrefabAssets which hides a property if it is drawn from a prefab asset.
      • Added a new attribute called HideInNonPrefabs which hides a property if it is drawn from a non prefab instance or asset.
      • Added a new attribute called DisableInPrefabInstances which disables a property if it is drawn from a prefab instance.
      • Added a new attribute called DisableInPrefabAssets which disables a property if it is drawn from a prefab asset.
      • Added a new attribute called DisableInNonPrefabs which disables a property if it is drawn from a non-prefab asset or instance.
    • Added a new attribute called HideInInlineEditors which hides a property if it is drawn within an InlineEditorAttribute.

    • Completely revamped the [ValidateInput] attribute. It can now detect changes to child values, as well as customize the error message and type - see the updated demo example. Additionally, it now also runs validation when an undo or redo is performed. Finally, support for preventing/rejecting invalid value changes has been removed from [ValidateInput], as it did not work correctly before in many cases, and proved infeasible to implement properly.

    • Upgrades to HorizontalGroup
      • Added PaddinLeft, PaddingRight, MinWidth and MaxWidth properties.
      • All properties now supports percentage. This includes Width, Min and Max Width, Padding and Margin. Values between 0 and 1 will be treated as percentage, 0 = ignored, otherwise pixels.
      • All properties are no longer private set.
      • Fixed an issue where horizontal groups start out too wide and slowly becomes the right size over time as the inspector window updates.
      • HorizontalGroup no longer sets the label width based on the width of the columns. This means that you can now do stuff like this: (and still maintain a proper label width which you couldn't do before).

    Fixes:
    • Fixed bug where Color and Color32 couldn't be properly copy pasted.
    • Unity's own context menu for Color and Color32 fields no longer shows up when the field is right-clicked.
    • Fixed issue where references to members with [HideInInspector] on them would not be drawn when the reference is expanded.
    • Fixed case where strings and boxed enums that were exact the same object instance would count as references to each other in the inspector.
    • Fixed rare error where changing a value's type between two different strongly typed list types would cause internal errors in the property system when updating a property's chlidren.
    • Fixed error where [ValueDropdown] wouldn't work properly with polymorphism.
    • Fixed error where [ValueDropdown] wouldn't work on list elements.
    • Fixed various errors with flag enums causing invalid cast exceptions. These should no longer happen, regardless of the enum's values and underlying type.
    • Fixed issue in DeepReflection with invalid IL code being emitted for invoking methods on value type instances. This was causing various attributes such as ShowIf and HideIf to throw exceptions when used in structs and referring to property and method members.
    • Fixed case where dictionaries that were referenced polymorphically would cause the inspector to break.
    • Fixed a lot of GUI Spaceing issues.
    • InfoBoxes now also work on methods.
    • Fixed issue, where int fields couldn't be changed with sliding, if mouse movement was too slow.
    • Fixed possible compiler error when compiling to iOS on xcode.
    • Fixed invalid generic argument exceptions being caused by enum serialization on the new .NET 4.6 scripting backend.
    • Fixed bug on the new 4.6 experimental scripting runtime where emitting a serialization formatter for an empty type with no values to serialize would cause Unity to crash, due to incorrect parsing of the emitted empty IL code.
    • Fixed compiler errors in new group system source code when using Unity's old compiler.
    • Fixed rare case where a missing editor type could cause compiler errors when generating editors.
    • MemberFinder now correctly includes the requested method parameters in the error message when it fails to find a member.
    • 1.0.4.1: Fixed case where AssemblyUtilities might throw an ArgumentOutOfRangeException when processing assemblies that are not located anywhere within the project folder.
    • 1.0.4.1: Fixed an issue where interacting with an object field in a box group, would cause all box backgrounds change color slightly.
    • 1.0.4.1: Button size now works with ButtonGroups.
    • 1.0.4.1: Fixed an issue where the hover effect for foldouts was delayed.

    Changes:
    • Lowered most error logs in DelegateFormatter to warning level, as many of them can occur in perfectly legitimate situations.
    • All members marked with [HideInInspector] now have a default property order value of int.MaxValue, by default placing them last in the order of properties. This ensures that it is only in very rare cases that there will be references to members that are hidden.
    • Enum flag names in the flag dropdown now have nicified names.
    • OdinEditorWindow now implements a scroll-view, and ensure the window is repainted when needed. A bit of padding around the drawn content has also been added.
    • DefaultSerializationBinder now also tries to resolve type names using AssemblyUtilities.GetType.
    • Slightly altered the sensitivity of field sliding to be a bit higher around a value of 0.
    • Updated Demo Scene and Documentation.
    • Improved error messages received when incorrectly applying the [ShowOdinSerializedPropertiesInInspector] attribute to classes that are not specially serialized and do not support special prefab serialization.
    • Property labels in tab groups now align with labels outside of tab groups.
    • Changed InfoBoxAttributeDrawer's priority to (0, 10001, 0)
    • Changed SpaceAttributeDrawer's priority to (1.1, 0, 0)
    Additions:
    • Added a very rudimentary Delegate drawer.
    • Odin now correctly guesses that fixed size buffers are serialized by Unity in version 2017.1 and up.
    • Added RectExtensions.ExpandTo.
    • Added new constructor to [OnInspectorGUI] that lets you specify two methods to invoke: a method to prepend, and a method to append.
    • Added support to Odin for drawing types derived from NetworkBehaviour, and added the SerializedNetworkBehaviour type. Note that [SyncVar] and SyncLists still have the exact same limitations as before, regardless of whether Odin is serializing the type or not.
    • The HideIf and Showif attributes now have an options to disable the fade in and fade out animations.
    • The DictionaryDrawerSettings attribute now has an option to marke a dictionary ReadOnly as well as changing the labels for the Key and Value columns.
    • Added a TextureUtilities class containing static helper functions.
    • Added support for injecting GUI before and after each element is drawin inside a list. This is achived using the [ListDrawerSettingsAttribute(OnBeginListElementGUI = "OnBeginListElementGUIMethodName", OnEndListElementGUI = "OnEndListElementGUIMethodName")].
    • Added support to the ListDrawerSettings attribute for defining custom label text for each list element. This is achived using the [ListDrawerSettingsAttribute(ListElementLabelName = "ListElementLabelName")].
    • Added PropertyTree.OnUndoRedoPerformed
    • 1.0.4.1: You can now override the number of items per page for lists via the ListDrawerSettings attribute.
    • 1.0.4.1: The TabGroup attribute now also supports naming tabs dynamically using the $ sign.

    • 1.0.4.1: Added a very rudimentary VerticalGroup attribute. This is particularly usefull if you want to make columns using HorizontalGroups.

      We'll be introducing more features to this attribute in the future.

    Check out Odin Inspector & Serializer on the Asset Store!
     
    Last edited: Jul 30, 2017
    Peter77 likes this.
  2. Dennin-Dalke

    Dennin-Dalke

    Joined:
    Aug 10, 2014
    Posts:
    25
    Hey guys, just to get an update, any news regarding UWP support? Is there any work around or any rudimentary support that would possible to use on this platform at the moment?
     
  3. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    There is currently no workaround I'm afraid. :( But we are actively working on it. If you want to get the build as soon as possible, and are up for testing it a bit as well, then shoot us an email with your Odin Invoice id (for verification), and I'll send you a build as soon as we have something working.
     
    Last edited: Aug 2, 2017
  4. Dennin-Dalke

    Dennin-Dalke

    Joined:
    Aug 10, 2014
    Posts:
    25
    I'll be definitely happy if I can help testing the builds, I sent the details to the support contact on the Sirenix site.
     
    bjarkeck likes this.
  5. jingray

    jingray

    Joined:
    Feb 6, 2015
    Posts:
    53
    While I execute as Button a function and Start game function miss ?!
     
  6. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    I'm afraid I'm not sure what exactly your issue is. Could you please clarify, or post some screenshots?
     
  7. SuneT

    SuneT

    Joined:
    Feb 29, 2016
    Posts:
    41
    Here's a GIF of the latest work on displaying lists and two-dimensional arrays as tables in Odin.

     
  8. Duffer123

    Duffer123

    Joined:
    May 24, 2015
    Posts:
    1,216
    Tables gui.... yes please.
     
    bjarkeck likes this.
  9. Dennin-Dalke

    Dennin-Dalke

    Joined:
    Aug 10, 2014
    Posts:
    25
    OMG Looks amazing! Good stuff!!
     
    bjarkeck likes this.
  10. pretender

    pretender

    Joined:
    Mar 6, 2010
    Posts:
    865
    is it possible to have scroll for texts/string or to have inline for TextAssets?
    great asset btw!
     
  11. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Thanks!

    Like this?

    Code (CSharp):
    1. [SerializeField]
    2. [TextArea(minLines: 10, maxLines: 20)]
    3. private string textArea;
    4.  
    5. [InlineEditor]
    6. [SerializeField]
    7. private TextAsset inlineTextAsset;
    I've just added a MaxHeight property to the InlineEditor attribute so that you can get a scroll wheel on that as well:

    Code (CSharp):
    1. [InlineEditor(MaxHeight = 200)]
    2. [SerializeField]
    3. private TextAsset inlineTextAsset;
    If the inline editor exceeds the specified maximum height, a scrollbar will appear. Setting MaxHeight to 0, will disable MaxHeight and show the entire Editor inline. Default MaxHeight is 0.

    asagfwe.png

    There is also the [OnInspectorGUI] attribute which is can be useful if you want a quick custom solution. In the next patch, we've added a new [CustomValueDrawer] attribute which is often an even better solution as it supports, multi-selection and undo, and can be combined with other attributes as well.

    CustomValueDrawer.gif

    If it doesn't quite suit your needs, or have any suggestions let me know :)
     
  12. pretender

    pretender

    Joined:
    Mar 6, 2010
    Posts:
    865
    That's great, it works!
    I was using SerializedScriptableObject but wanted to convert to OdinEditorWindow, it works good but i have noticed that it doesn't serialize, list are cleared every time when i open window also, all other things are nulled...is there something that i am missing?

    also i can't name the window, i tried

    Code (CSharp):
    1. var window =  GetWindow<InfoWindow>()
    2. window.name = "window";
    3. window.Show();
    but it doesn't work

    thank! this asset is essential!
     
  13. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Yeah, Editor windows do not store any permanent data out of the box. They are destroyed whenever you close them, so you still need to store the data somewhere, somehow, manually. If you want to store the data per-user, you can use Unity's EditorPrefs.Get/SetField, or you could keep your SerializedObject, and just draw that directly in the EditorWindow if you want. That is btw actually exactly what we are doing in the Odin Preferences window. Each editor within the window is just a ScriptableObject, that has an attribute telling what menu item it is.

    https://jumpshare.com/v/E85cHTytRusmtMI07LEs

    Instead of inheriting from ScriptableObject directly, we have a GlobalConfig base-class that is basically a ScriptableObject singleton. It's quite handy, for cases exactly like this.

    You can see the documentation for it here:

    http://sirenix.net/odininspector/documentation/sirenix/utilities/globalconfig(t)

    You can draw a ScriptableObject in an EditorWindow like this:
    Code (CSharp):
    1.  
    2. public class InfoWindow : EditorWindow
    3. {
    4.      private Vector2 scrollPos;
    5.      private Editor editor;
    6.  
    7.      [MenuItem("Test/Test")]
    8.      private static void OpenWindow()
    9.      {
    10.           GetWindow<InfoWindow>().Show();
    11.      }
    12.  
    13.      private void OnEnable()
    14.      {
    15.           this.editor = Editor.CreateEditor(InfoDataSingleton.Instance);
    16.      }
    17.  
    18.      private void OnGUI()
    19.      {
    20.           this.scrollPos = EditorGUILayout.BeginScrollView(this.scrollPos);
    21.           GUIHelper.PushHierarchyMode(false);
    22.           this.editor.OnInspectorGUI();
    23.           GUIHelper.PopHierarchyMode();
    24.           EditorGUILayout.EndScrollView();
    25.  
    26.           this.RepaintIfRequested();
    27.      }
    28.  
    29.      private void OnDestroy()
    30.      {
    31.           DestroyImmediate(this.editor);
    32.      }
    33. }
    34.  
     
    Last edited: Aug 14, 2017
  14. zsaladin

    zsaladin

    Joined:
    Jan 20, 2015
    Posts:
    11
    Hi.
    Thank you for providing this awesome asset.
    This is my favorite asset.

    I usually use it on serializing Dictionary.
    But I have faced a problem of it.

    I just added simple codes like this.

    Code (CSharp):
    1. public class TestSerialization : SerializedMonoBehaviour
    2. {
    3.     [SerializeField] Dictionary<int, GameObject> _test;
    4. }
    I've tried to drag and drop this prefab on Hierarchy.
    Then Unity Editor crashed or froze on Windows and Mac.
    Sometimes it depends on the number of Dictionary's items.
    I tested it on 5.5.2f, 5.6.0f3, 5.6.3f1 and 2017.1.0f3. It occurs on all of them.

    I attached the sample project able to reproduce it.
    You just drag and drop the object named 'GameObject' located in 'Assets/' on any scene.
    Also Odin asset is excluded from this sample. So you should add Odin asset before test.
     

    Attached Files:

    Last edited: Aug 15, 2017
  15. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Thank you, nice to hear you like it, thanks! And thank you for providing the sample, We'll have a look at this tomorrow and give you an update.
     
  16. pretender

    pretender

    Joined:
    Mar 6, 2010
    Posts:
    865
    Thanks for looking into this, that was what i needed!
    I was wondering is it possible to have list displayed horizontally? I have some sprite list that would be nice to display horizontally? Is it possible?
     
  17. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Not ATM atm I'm afraid. But I've added it to our list of suggestions.:) If you want to go through the trouble of making something custom for your specific use case. You could hide the list itself using HideInInspector, then add a method with an OnInspectorGUI attribute, and start using GUILayout etc to build your custom UI. But introducing something like an HorizontalList attribute or a ListGallery attribute would currently require a lot of work. Our current ListDrawer is 900 lines of nightmare. But I do like the idea of some gallery type list view!
     
  18. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    Is it possible to color a whole BoxGroup? Or individual cells in them even?
     
    Last edited: Aug 16, 2017
  19. waheyluggage

    waheyluggage

    Joined:
    Aug 22, 2015
    Posts:
    15
    Hello

    This looks interesting, does it support cross referencing gameobjects across scenes? Like if I have 2 scene files loaded in Unity, then drag a GameObject from scene 1 onto a property for an object in scene 2, will that serialize correctly once my game loads up and I've loaded both scenes back in? Thanks!
     
  20. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    Hey, and thanks for the report!

    This is a deeply mystifying issue. After much trial and error, we have narrowed it down to an internal Unity crash that only happens under very exact circumstances. It is not dictionary related. It seems that it only happens if you are referencing GameObjects in the same prefab instance's modifications, that have components on them related to Unity's UI system. (Odd, right?)

    We have cooked up a small demo project that reliably reproduces this issue, and submitted an issue to Unity. We'll keep you up to date as we receive more information from Unity regarding the issue.

    Meanwhile, for now, we have to advise you not to use Odin-serialized Unity object references in prefabs that are to be used in your UI.

    Additionally, you should know that there are some other currently known issues with Odin-serialized Unity object references acting oddly in prefab instances generally. We have fixed most of these in our working branches, and a full array of fixes will make it into the next patch, which is perhaps two weeks out (it is a *big* patch). Meanwhile, you may just want to avoid referencing Unity objects in Odin-serialized prefab instances entirely - but as they do mostly work reliably when not referencing objects internal to the prefab itself, we of course leave that decision up to you :)

    If you have any further questions, please don't hesitate to ask.
     
    Last edited: Aug 18, 2017
  21. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    We only support cross-scene object references to the exact same degree that Unity itself does, so we're afraid that we don't add anything new in that area.
     
  22. waheyluggage

    waheyluggage

    Joined:
    Aug 22, 2015
    Posts:
    15
    Ah right, thanks for the quick reply and sorry for cross posting it, I posted to this forum then wondered if it was an old one.

    Unity doesn't appear to support saving cross-scene object references from the editor, which makes sense. I can change the editor to allow assigning of them, but they don't serialize unfortunately.

    My alternative option method is to save the name of the gameobject instead, then when the game runs do a Find to put get the reference back. I was hoping Odin could make this transparent or at least less manual :D.
     
  23. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    I'm going to keep referring back to Advanced Inspector because it has done right by me for so long - but is there an equivalent to "ShowInParent"? ie: show the contents of my inside of whatever owns me instead?

    It allows us to clean up some data grossness at the UI level.
     
  24. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Hi KJoanette,

    Thank's for your feedback.

    You can use the GUIColor attribute to color individual fields, properties, and even methods.

    Code (CSharp):
    1.  
    2. public class MyComponent : MonoBehaviour
    3. {
    4.     [GUIColor(0, 1, 0)]
    5.     public int ColoredField;
    6.  
    7.     [Button, GUIColor(1, 0, 0)]
    8.     public void ColoredButton()
    9.     {
    10.  
    11.     }
    12. }
    I've added a GUIColorGroup attribute to our list of suggestions. :)

    Yeah, I believe the equivalent of that would be hiding the label?

    Here are some random combinations showing how you can combine various attributes to get something nice looking.

    Code (CSharp):
    1. public class MyComponent : MonoBehaviour
    2. {
    3.     public MyClass MyField1;
    4.  
    5.     [HideLabel]
    6.     [Title("MyField2")]
    7.     public MyClass MyField2;
    8.  
    9.     [HideLabel]
    10.     [BoxGroup("MyField3")]
    11.     public MyClass MyField3;
    12.  
    13.     [InlineProperty(LabelWidth = 15)]
    14.     public MyClass MyField4;
    15.  
    16.     [Indent]
    17.     [InlineProperty(LabelWidth = 15)]
    18.     public MyClass MyField5;
    19. }
    20.  
    21. [Serializable]
    22. public class MyClass
    23. {
    24.     public int A, B, C;
    25. }
    fafaf.png

    You can also put the InlineEditor attribute on the class itself if you want it to appear like in the editor always. Here is an example of that:
    inlineproperty.png

    Hope it was something like that you meant with DisplayAsParent?
     
    Last edited: Aug 18, 2017
  25. zephyr7

    zephyr7

    Joined:
    Oct 12, 2013
    Posts:
    16
    Just recently started using this. Pretty awesome, liking it so far except for the lack of documentation. Really looking forward to the 2d array support.

    Question/Suggestion:
    I have a ton of rpg attribute tables on my items and I'm wondering if it'd be possible to control the GUIColor attribute conditionally - as a simple example, just an int field that is drawn in normal gray if it's 0, and drawn in green if it's not 0. This could be very useful when handling bigger stat sets.

    But there's no way for me to reference the GUIColor attributes per variable they belong to, or is there?
     
  26. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    This can pretty easily be done with a small one-off custom drawer. The following code declares a [Stat] attribute, and a drawer for that attribute that works on all primitive types and strings. It colors the drawn value green, if the value to be drawn is not the default value of the drawn type.

    So you can put the [Stat] attribute on any of your primitive fields, and it'll be colored green if the value has been changed from the default one. Of course, you can tweak the logic here to be anything you like, or pass in any sort of custom per-property parameters via the Stat attribute itself.

    Code (CSHARP):
    1. using System;
    2. using UnityEngine;
    3. using Sirenix.OdinInspector;
    4.  
    5. #if UNITY_EDITOR
    6.  
    7. using Sirenix.OdinInspector.Editor;
    8. using Sirenix.Utilities.Editor;
    9.  
    10. #endif
    11.  
    12. public class MyMonoBehaviour : SerializedMonoBehaviour
    13. {
    14.     [Stat]
    15.     public string stringStat;
    16.  
    17.     [Stat]
    18.     public int intStat;
    19.  
    20.     [Stat]
    21.     public float floatStat;
    22.  
    23.     [Stat]
    24.     public byte byteStat;
    25.  
    26.     [Stat]
    27.     public bool boolStat;
    28. }
    29.  
    30. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
    31. public sealed class StatAttribute : Attribute
    32. {
    33. }
    34.  
    35. #if UNITY_EDITOR
    36.  
    37. [OdinDrawer]
    38. public sealed class StatDrawer<T> : OdinAttributeDrawer<StatAttribute, T>
    39. {
    40.     public override bool CanDrawTypeFilter(Type type)
    41.     {
    42.         return type.IsPrimitive || type == typeof(string);
    43.     }
    44.  
    45.     protected override void DrawPropertyLayout(IPropertyValueEntry<T> entry, StatAttribute attribute, GUIContent label)
    46.     {
    47.         bool changedValue = false;
    48.  
    49.         if (typeof(T) == typeof(string))
    50.         {
    51.             string value = (string)entry.WeakSmartValue;
    52.  
    53.             if (value != null && value.Length > 0)
    54.             {
    55.                 changedValue = true;
    56.             }
    57.         }
    58.         else
    59.         {
    60.             if (!entry.SmartValue.Equals(default(T)))
    61.             {
    62.                 changedValue = true;
    63.             }
    64.         }
    65.  
    66.         if (changedValue)
    67.         {
    68.             GUIHelper.PushColor(Color.green);
    69.             this.CallNextDrawer(entry, label);
    70.             GUIHelper.PopColor();
    71.         }
    72.         else
    73.         {
    74.             this.CallNextDrawer(entry, label);
    75.         }
    76.     }
    77. }
    78.  
    79. #endif
    It ends up looking like this in the inspector:



    Hope that sheds some light on how to do stuff like this! We're aware of the somewhat lacking documentation, and are making a big push to correct this before the next big (!) patch comes out. We're holding some dedicated documentation days soon, where we'll be adding an extensive FAQ, finishing off big parts of the manual, polishing up our website a bit, and more stuff like that.
     
  27. zephyr7

    zephyr7

    Joined:
    Oct 12, 2013
    Posts:
    16
    Awesome, thank you very much. That's exactly the behavior i was looking for. Is there a way to get this to work on single values inside a struct, too? So far I've only managed to make it color the entire struct if any part of it was changed.
     
  28. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    You'd have to apply it to whichever field inside the struct you want to have the behaviour, I'm afraid. So if you're working with, say, a Vector3, you're a little out of luck, for now. There are ways, but they are a little hacky. You could take over the drawing of the entire struct from the Stat attribute drawer, for example, by getting all its children via entry.Property.Children and calling Draw() on each of them in turn, checking their values (through their value entries) and wrapping each individually in a color if necessary. You can look at the CompositeDrawer.cs in Odin's source code to see how that sort of stuff is usually done.

    In the future, for patch 1.1, we're going to do a refactor of our property system internals that'll let you apply attributes to types and their members in a wide variety of ways, both dynamically and statically, even if you don't have access to the type's source code yourself.
     
  29. zephyr7

    zephyr7

    Joined:
    Oct 12, 2013
    Posts:
    16
    I think i'll wait for 1.1 then - great to hear this is coming. Really excited to see where this project goes :) Again thank you for the great product and support.
     
  30. PIGSSS-GAMES

    PIGSSS-GAMES

    Joined:
    Jul 2, 2014
    Posts:
    8
    I'm looking for a way to:
    - Generate dynamic buttons
    - Create command that make [ListDrawerSettings(NumberOfItemsPerPage = X)] jump to desire page.

    My use case is it that I have a very long list of Object Class. And I would like to make dynamic buttons (may be with sub page/tabs) with a name so the designer can just click that button and then jump to correct page where that class located.
     
  31. Netbandit

    Netbandit

    Joined:
    Feb 16, 2014
    Posts:
    18
    Hi,

    I have an array which should be shown in the inspector. Every array member corresponds to an enumeration value, which means, for every enumeration value there is one member in the array. Now I wonder, if I can see the enumeration values as index label in the inspector?

    This is a code example. I'm searching for a ListDrawerSetting like "ShowEnumLabels".

    Code (CSharp):
    1.  
    2. enum Directions
    3. {
    4.   Left,
    5.   Right
    6. }
    7.  
    8. [ShowInInspector]
    9. [ListDrawerSettings(IsReadOnly = true, ShowIndexLabels = true, ShowEnumLabels=Directions)]
    10. public ITile[] TileArray = new ITile[2];
    11.  
     
  32. alialharbi

    alialharbi

    Joined:
    May 4, 2014
    Posts:
    2
    Hi we have purchased today, and after building ios version we will getting bellow error continuously.

    Below is log from Xcode

    Code (CSharp):
    1. ExecutionEngineException: Attempting to call method 'Sirenix.Serialization.ComplexTypeSerializer`1[[System.Nullable`1[[UnityEngine.Vector3, UnityEngine, Version=0.0.0.0, Culture=, PublicKeyToken=null]], mscorlib, Version=2.0.0.0, Culture=, PublicKeyToken=b77a5c561934e089]]::.cctor' for which no ahead of time (AOT) code was generated.
    2.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    3.   at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <filename unknown>:0
    4.   at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <filename unknown>:0
    5.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    6.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    7.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    8.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    9. Rethrow as TypeInitializationException: The type initializer for 'Sirenix.Serialization.ComplexTypeSerializer<System.Nullable<UnityEngine.Vector3>>' threw an exception.
    10.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    11.   at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <filename unknown>:0
    12.   at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <filename unknown>:0
    13.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    14.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    15.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    16.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    17. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    18.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    19.   at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <filename unknown>:0
    20.   at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <filename unknown>:0
    21.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    22.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    23.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    24.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    25. (Filename: currently not available on il2cpp Line: -1)
    26.  
    27. ExecutionEngineException: Attempting to call method 'Sirenix.Serialization.DictionaryFormatter`2[[Sirenix.OdinInspector.Demos.MyEnum, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=, PublicKeyToken=null],[Sirenix.OdinInspector.Demos.DictionaryExamples+MyCustomType, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=, PublicKeyToken=null]]::.cctor' for which no ahead of time (AOT) code was generated.
    28.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    29.   at Sirenix.Serialization.FormatterLocator.CreateFormatter (System.Type type, ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    30.   at Sirenix.Serialization.FormatterLocator.GetFormatter (System.Type type, ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    31.   at Sirenix.Serialization.FormatterLocator.GetFormatter[T] (ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    32.   at Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (IDataReader reader) [0x00000] in <filename unknown>:0
    33.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    34.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    35.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    36.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    37. Rethrow as TypeInitializationException: The type initializer for 'Sirenix.Serialization.DictionaryFormatter<Sirenix.OdinInspector.Demos.MyEnum,Sirenix.OdinInspector.Demos.DictionaryExamples.MyCustomType>' threw an exception.
    38.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    39.   at Sirenix.Serialization.FormatterLocator.CreateFormatter (System.Type type, ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    40.   at Sirenix.Serialization.FormatterLocator.GetFormatter (System.Type type, ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    41.   at Sirenix.Serialization.FormatterLocator.GetFormatter[T] (ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    42.   at Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (IDataReader reader) [0x00000] in <filename unknown>:0
    43.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    44.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    45.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    46.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    47. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    48.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    49.   at Sirenix.Serialization.FormatterLocator.CreateFormatter (System.Type type, ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    50.   at Sirenix.Serialization.FormatterLocator.GetFormatter (System.Type type, ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    51.   at Sirenix.Serialization.FormatterLocator.GetFormatter[T] (ISerializationPolicy policy) [0x00000] in <filename unknown>:0
    52.   at Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (IDataReader reader) [0x00000] in <filename unknown>:0
    53.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    54.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    55.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    56.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    57. Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader)
    58. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, IDataReader)
    59. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, Byte[]&, List`1&, DataFormat, DeserializationContext)
    60. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext, Boolean)
    61. Sirenix.OdinInspector.SerializedMonoBehaviour:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize()
    62. (Filename: currently not available on il2cpp Line: -1)
    63.  
    64. Expected TypeName, TypeID or UnnamedNull entry flag for reading type data, but instead got the entry flag: Invalid.
    65. Sirenix.Serialization.BinaryDataReader:ReadTypeEntry()
    66. Sirenix.Serialization.BinaryDataReader:EnterNode(Type&)
    67. Sirenix.Serialization.BaseDataReader:SkipEntry()
    68. Sirenix.Serialization.BaseDataReader:SkipEntry()
    69. Sirenix.Serialization.BinaryDataReader:ExitNode()
    70. Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader)
    71. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, IDataReader)
    72. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, Byte[]&, List`1&, DataFormat, DeserializationContext)
    73. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext, Boolean)
    74. Sirenix.OdinInspector.SerializedMonoBehaviour:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize()
    75. (Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
    76.  
    77. Expected TypeName, TypeID or UnnamedNull entry flag for reading type data, but instead got the entry flag: Invalid.
    78. Sirenix.Serialization.BinaryDataReader:ReadTypeEntry()
    79. Sirenix.Serialization.BinaryDataReader:EnterNode(Type&)
    80. Sirenix.Serialization.BaseDataReader:SkipEntry()
    81. Sirenix.Serialization.BaseDataReader:SkipEntry()
    82. Sirenix.Serialization.BinaryDataReader:ExitNode()
    83. Sirenix.Serialization.BaseDataReader:SkipEntry()
    84. Sirenix.Serialization.BaseDataReader:SkipEntry()
    85. Sirenix.Serialization.BinaryDataReader:ExitNode()
    86. Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader)
    87. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, IDataReader)
    88. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, Byte[]&, List`1&, DataFormat, DeserializationContext)
    89. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext, Boolean)
    90. Sirenix.OdinInspector.SerializedMonoBehaviour:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize()
    91. (Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
    92.  
    93. ExecutionEngineException: Attempting to call method 'Sirenix.Serialization.ComplexTypeSerializer`1[[UnityEngine.Quaternion, UnityEngine, Version=0.0.0.0, Culture=, PublicKeyToken=null]]::.cctor' for which no ahead of time (AOT) code was generated.
    94.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    95.   at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <filename unknown>:0
    96.   at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <filename unknown>:0
    97.   at Sirenix.Serialization.ReflectionFormatter`1[T].DeserializeImplementation (.T& value, IDataReader reader) [0x00000] in <filename unknown>:0
    98.   at Sirenix.Serialization.BaseFormatter`1[T].Deserialize (IDataReader reader) [0x00000] in <filename unknown>:0
    99.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    100.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    101.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    102.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    103.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    104.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    105.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    106.   at Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (IDataReader reader) [0x00000] in <filename unknown>:0
    107.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    108.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    109.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    110.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    111. Rethrow as TypeInitializationException: The type initializer for 'Sirenix.Serialization.ComplexTypeSerializer<UnityEngine.Quaternion>' threw an exception.
    112.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    113.   at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <filename unknown>:0
    114.   at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <filename unknown>:0
    115.   at Sirenix.Serialization.ReflectionFormatter`1[T].DeserializeImplementation (.T& value, IDataReader reader) [0x00000] in <filename unknown>:0
    116.   at Sirenix.Serialization.BaseFormatter`1[T].Deserialize (IDataReader reader) [0x00000] in <filename unknown>:0
    117.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    118.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    119.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    120.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    121.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    122.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    123.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    124.   at Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (IDataReader reader) [0x00000] in <filename unknown>:0
    125.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    126.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    127.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    128.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    129. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    130.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    131.   at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <filename unknown>:0
    132.   at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <filename unknown>:0
    133.   at Sirenix.Serialization.ReflectionFormatter`1[T].DeserializeImplementation (.T& value, IDataReader reader) [0x00000] in <filename unknown>:0
    134.   at Sirenix.Serialization.BaseFormatter`1[T].Deserialize (IDataReader reader) [0x00000] in <filename unknown>:0
    135.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    136.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    137.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    138.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    139.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    140.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    141.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    142.   at Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (IDataReader reader) [0x00000] in <filename unknown>:0
    143.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    144.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    145.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    146.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    147. Sirenix.Serialization.ReflectionFormatter`1:DeserializeImplementation(T&, IDataReader)
    148. Sirenix.Serialization.BaseFormatter`1:Deserialize(IDataReader)
    149. Sirenix.Serialization.BaseDataReader:SkipEntry()
    150. Sirenix.Serialization.BinaryDataReader:ExitNode()
    151. Sirenix.Serialization.BaseDataReader:SkipEntry()
    152. Sirenix.Serialization.BinaryDataReader:ExitNode()
    153. Sirenix.Serialization.BaseDataReader:SkipEntry()
    154. Sirenix.Serialization.BaseDataReader:SkipEntry()
    155. Sirenix.Serialization.BinaryDataReader:ExitNode()
    156. Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader)
    157. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, IDataReader)
    158. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, Byte[]&, List`1&, DataFormat, DeserializationContext)
    159. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext, Boolean)
    160. Sirenix.OdinInspector.SerializedMonoBehaviour:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize()
    161. (Filename: currently not available on il2cpp Line: -1)
    162.  
    163. ExecutionEngineException: Attempting to call method 'Sirenix.Serialization.ComplexTypeSerializer`1[[UnityEngine.Quaternion, UnityEngine, Version=0.0.0.0, Culture=, PublicKeyToken=null]]::.ctor' for which no ahead of time (AOT) code was generated.
    164.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    165.   at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <filename unknown>:0
    166.   at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <filename unknown>:0
    167.   at Sirenix.Serialization.ReflectionFormatter`1[T].DeserializeImplementation (.T& value, IDataReader reader) [0x00000] in <filename unknown>:0
    168.   at Sirenix.Serialization.BaseFormatter`1[T].Deserialize (IDataReader reader) [0x00000] in <filename unknown>:0
    169.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    170.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    171.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    172.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    173.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    174.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    175.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    176.   at Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (IDataReader reader) [0x00000] in <filename unknown>:0
    177.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    178.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    179.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    180.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    181. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    182.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    183.   at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <filename unknown>:0
    184.   at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <filename unknown>:0
    185.   at Sirenix.Serialization.ReflectionFormatter`1[T].DeserializeImplementation (.T& value, IDataReader reader) [0x00000] in <filename unknown>:0
    186.   at Sirenix.Serialization.BaseFormatter`1[T].Deserialize (IDataReader reader) [0x00000] in <filename unknown>:0
    187.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    188.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    189.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    190.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    191.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    192.   at Sirenix.Serialization.BaseDataReader.SkipEntry () [0x00000] in <filename unknown>:0
    193.   at Sirenix.Serialization.BinaryDataReader.ExitNode () [0x00000] in <filename unknown>:0
    194.   at Sirenix.Serialization.ComplexTypeSerializer`1[T].ReadValue (IDataReader reader) [0x00000] in <filename unknown>:0
    195.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, IDataReader reader) [0x00000] in <filename unknown>:0
    196.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, System.Byte[]& bytes, System.Collections.Generic.List`1& referencedUnityObjects, DataFormat format, Sirenix.Serialization.DeserializationContext context) [0x00000] in <filename unknown>:0
    197.   at Sirenix.Serialization.UnitySerializationUtility.DeserializeUnityObject (UnityEngine.Object unityObject, SerializationData& data, Sirenix.Serialization.DeserializationContext context, Boolean isPrefabData) [0x00000] in <filename unknown>:0
    198.   at Sirenix.OdinInspector.SerializedMonoBehaviour.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize () [0x00000] in <filename unknown>:0
    199. Sirenix.Serialization.ReflectionFormatter`1:DeserializeImplementation(T&, IDataReader)
    200. Sirenix.Serialization.BaseFormatter`1:Deserialize(IDataReader)
    201. Sirenix.Serialization.BaseDataReader:SkipEntry()
    202. Sirenix.Serialization.BinaryDataReader:ExitNode()
    203. Sirenix.Serialization.BaseDataReader:SkipEntry()
    204. Sirenix.Serialization.BinaryDataReader:ExitNode()
    205. Sirenix.Serialization.BaseDataReader:SkipEntry()
    206. Sirenix.Serialization.BaseDataReader:SkipEntry()
    207. Sirenix.Serialization.BinaryDataReader:ExitNode()
    208. Sirenix.Serialization.ComplexTypeSerializer`1:ReadValue(IDataReader)
    209. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, IDataReader)
    210. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, Byte[]&, List`1&, DataFormat, DeserializationContext)
    211. Sirenix.Serialization.UnitySerializationUtility:DeserializeUnityObject(Object, SerializationData&, DeserializationContext, Boolean)
    212. Sirenix.OdinInspector.SerializedMonoBehaviour:UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize()
    213. (Filename: currently not available on il2cpp Line: -1)
    214.  
    215.  
    216. And this last error is continuously coming
     
  33. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    This happens because Unity's IL2CPP converter fails to generate the generic type and method variants that Odin's serialization system needs in order to work. As I mentioned on our issue tracker, the newest patch, 1.0.5, has the ability to scan your project and generate a .dll that fixes this issue. Please send me a mail with your Odin invoice number at tor@sirenix.net, and I'll send you our latest build right away.
     
  34. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    This is quite easily doable! You can use the OnBeginListElementGUI and OnEndListElementGUI arguments to do this. Take for example this code:

    Code (CSharp):
    1. public class MyMonoBehaviour : SerializedMonoBehaviour
    2. {
    3.     public enum Directions
    4.     {
    5.         Left,
    6.         Right
    7.     }
    8.  
    9.     [ListDrawerSettings(IsReadOnly = true, OnBeginListElementGUI = "ListIndexGUIBegin", OnEndListElementGUI = "ListIndexGUIEnd")]
    10.     public string[] list = new string[2];
    11.  
    12. #if UNITY_EDITOR
    13.  
    14.     private void ListIndexGUIBegin(int index)
    15.     {
    16.         GUILayout.BeginHorizontal();
    17.         GUILayout.Label(((Directions)index).ToString(), UnityEditor.EditorStyles.popup, GUILayoutOptions.Width(75));
    18.     }
    19.  
    20.     private void ListIndexGUIEnd(int index)
    21.     {
    22.         GUILayout.EndHorizontal();
    23.     }
    24.  
    25. #endif
    26. }
    Which results in this inspector:



    We took some time to speak about this together, brainstorming solutions, and we're afraid there isn't currently a straightforward way to do this. We'll consider adding one in the future - meanwhile, you'll have to make do with, for example, showing a "temporary" non-serialized list of all elements that match the search conditions, using [ShowInInspector] - or you can just write which page the given object is on.
     
    Last edited: Aug 24, 2017
  35. jingray

    jingray

    Joined:
    Feb 6, 2015
    Posts:
    53
    Supporter and asset. Very very good. :p
     
  36. Netbandit

    Netbandit

    Joined:
    Feb 16, 2014
    Posts:
    18
    Thanks! This was exactly what I was looking for. You should add this "trick" to the documentation :)
     
  37. Abuthar

    Abuthar

    Joined:
    Jul 12, 2014
    Posts:
    92
    Question about tab groups...

    Is there a way I can put all my variables in a tab group without having to do this:

    [TabGroup("Group 1")]
    public int a;
    [TabGroup("Group 1")]
    public int b;
    [TabGroup("Group 1")]
    public int c;

    I know this doesn't work, but for example:

    [TabGroup("Group 1")]
    {
    public int a;
    public int b;
    public int c;
    }

    I've looked around for a couple hours now and I can usually figure things out fairly quickly, but I'm guessing there's no way to do this?
     
  38. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    We're afraid C#'s syntax doesn't allow that, no. You'll have to apply the attribute to every member that you want to be part of the group.
     
    Abuthar likes this.
  39. Abuthar

    Abuthar

    Joined:
    Jul 12, 2014
    Posts:
    92
    Thank you veyr much for the prompt response. That's what i've done for now, which is kinda tedious with 200+ unique elements.
     
  40. c0ffeeartc

    c0ffeeartc

    Joined:
    Jul 23, 2015
    Posts:
    42
    Hello. I'd like to limit polymorphic types dropdown by either list of types or by presence of arbitrary Attribute.
    For example
    Code (CSharp):
    1. [A1] public class A : ICommon{}
    2. [B1] public class B : ICommon{}
    3. public static readonly System.Type[] AllA1Types = {};
    4. public static readonly System.Type[] AllB1Types = {};
    5.  
    6. public class Some : SerializedBehaviour{
    7. //[UseTypes("AllA1Types")] // or [UseTypesWithAttribute("A1")]
    8.  public ICommon Value;
    9. }
    Is it possible?
     
  41. c0ffeeartc

    c0ffeeartc

    Joined:
    Jul 23, 2015
    Posts:
    42
    Another one - in FullInspector it's possible to write following, and polymorphic dropdown will show generic classes Some1<String>, Some2<String> in dropdown.
    Code (CSharp):
    1. public interface ISome<T>{}
    2. public class Some1<T> : ISome<T>{}
    3. public class Some2<T> : ISome<T>{}
    4.  
    5. public class Container : SerializedBehaviour{
    6.     public ISome<String> Value;
    7. }
     
  42. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    301
    Hi c0ffeeartc,

    This is currently not possible out of the box I'm afraid. But it's defiantly something we want in the future. We are working on an entirely new replacement for the instance creator window. The new window will be able to create new instances while handling things like constructors nicely, or even fetch instances from anywhere - the scene, the project, the inspected object itself, or something completely custom and user-defined. If you are resolving an interface, it can find scene components or assets implementing that interface, and so on. It will be highly extendable and configurable.

    For now, you could either roll out something custom or maybe give the user an error with the ValidateInput attribute if they select an invalid type

    Completly forgot about cases like that. I've just added support for it and it'll be there in the next Odin Inspector 1.0.5 path which is currently in beta.

    If you want, you can send us an email with your Odin Inspector invoice id (for verification), and we'll send you the latest beta build, which will include this fix.

    fix3.png
     
    Last edited: Aug 27, 2017
  43. c0ffeeartc

    c0ffeeartc

    Joined:
    Jul 23, 2015
    Posts:
    42
    Looks great, thanks. Will send id
     
    bjarkeck likes this.
  44. LootlabGames

    LootlabGames

    Joined:
    Nov 21, 2014
    Posts:
    343
    Getting an error I can't seem to fix.
    I have deleted and reimported Odin and get the same problem.

    Here is the error:
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. Sirenix.Utilities.PropertyInfoExtensions.IsAutoProperty (System.Reflection.PropertyInfo propInfo) (at C:/Users/tor_v/Documents/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Utilities/Extensions/PropertyInfoExtensions.cs:30)
    3. Sirenix.Serialization.FormatterUtilities.FindSerializableMembers (System.Type type, System.Collections.Generic.List`1 members, ISerializationPolicy policy) (at C:/Users/tor_v/Documents/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Serialization/Utilities/FormatterUtilities.cs:311)
    4. Sirenix.Serialization.FormatterUtilities.FindSerializableMembers (System.Type type, System.Collections.Generic.List`1 members, ISerializationPolicy policy) (at C:/Users/tor_v/Documents/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Serialization/Utilities/FormatterUtilities.cs:302)
    5. Sirenix.Serialization.FormatterUtilities.GetSerializableMembers (System.Type type, ISerializationPolicy policy) (at C:/Users/tor_v/Documents/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Serialization/Utilities/FormatterUtilities.cs:117)
    6. Sirenix.Serialization.UnitySerializationUtility.SerializeUnityObject (UnityEngine.Object unityObject, IDataWriter writer, Boolean serializeUnityFields) (at C:/Users/tor_v/Documents/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Serialization/Utilities/UnitySerializationUtility.cs:739)
    7. Sirenix.Serialization.UnitySerializationUtility.SerializeUnityObject (UnityEngine.Object unityObject, Sirenix.Serialization.SerializationData& data, Boolean serializeUnityFields, Sirenix.Serialization.SerializationContext context) (at C:/Users/tor_v/Documents/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Serialization/Utilities/UnitySerializationUtility.cs:479)
    8. Sirenix.OdinInspector.SerializedScriptableObject.UnityEngine.ISerializationCallbackReceiver.OnBeforeSerialize () (at C:/Users/tor_v/Documents/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Serialization/Unity Integration/SerializedScriptableObject.cs:30)
    9.  
    One thing to note is that it seems to be looking for a user that doesn't exist: "Users/tor_v/"
     
  45. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    Hi. This is a known issue, which has been resolved in the next patch, which will be released on the asset store very soon. If you'd like, you can send me your invoice number at tor@sirenix.net, and I'll send you our release candidate build.
     
  46. Azmar

    Azmar

    Joined:
    Feb 23, 2015
    Posts:
    246
    I have a scriptable object that has a dictionary with <enum, Sprite>, this code works perfectly with odin as expected.

    Code (CSharp):
    1. [CreateAssetMenu(fileName = "CreatureAsset", menuName = "Asset/Creature Asset", order = 1)]
    2. public class CreatureAsset : SerializedScriptableObject
    3. {
    4.  
    5.     public Dictionary<CreatureData.ColourType, Sprite> ColourDictionary;
    6. }
    7.  
    But I wanted to create a special editor for it through a different class that has inherited editor, or OdinEditor. I have special utility extensions that only work from inherit editor, and I like to separate it.
    Code (CSharp):
    1. [CustomEditor(typeof(CreatureAsset))]
    2. [CanEditMultipleObjects]
    3. public class CreatureAssetEditor : OdinEditor
    4. {
    5.     private CreatureAsset _extension;
    6.  
    7.     protected override void OnEnable()
    8.     {
    9.         _extension = (CreatureAsset) serializedObject.targetObject;
    10.     }
    11.  
    12.     public override void OnInspectorGUI()
    13.     {
    14.         serializedObject.Update();
    15.  
    16.         DrawDefaultInspector();
    17.  
    18.         if (GUILayout.Button("Setup"))
    19.         {
    20.             Setup();
    21.         }
    22.         serializedObject.ApplyModifiedProperties();
    23.     }
    24. ...
    25. }
    Now when I do this I lose the serialization of the dictionary that I had before. How would I get this to work through my "CreatureAssetEditor" class? I understand "DrawDefaultInspector()" is not for Odin inspector, but I don't know the solution when doing this for Odin. I don't want to create my own drawers for my dictionary, as the documentation itself is still rough to understand.
     
  47. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    You should call base.OnInspectorGUI() instead of DrawDefaultInspector() - that will make the OdinEditor base class draw Odin's regular inspector.
     
  48. Azmar

    Azmar

    Joined:
    Feb 23, 2015
    Posts:
    246
    Oh I see thanks, got it to work! Also I have another question, and not sure if this is Unity or Odin Inspector. But let's say if I click on my ScriptableObject asset and I have a dictionary that shows all the keys, values and I minimize/fold them so I don't see the keys,values as its easier to read. When I click off the asset and click back on the asset it is unminimized/unfolded every time. Any way to lock the folding or auto folding or something?
     
  49. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    The next patch has a persistent context system - so stuff like what is folded and unfolded, or which tab is selected, and so on, will remain persistent, and Odin will remember it whenever you select another object and then come back. It will even remember it after a script reload, and after the editor is restarted. We're submitting the patch today, so it shouldn't be more than a few days before it goes live!
     
  50. zzzzzz789

    zzzzzz789

    Joined:
    Dec 21, 2013
    Posts:
    22
    @Tor-Vestergaard
    Is there an easy way to make something like an info box without having to have it be an attribute to another variable? I want to add an explanation header to the top of my script, but if I connect it to another variable it shares with same attributes, such as GUIColor or ShowIf HideIf