Search Unity

  1. Check out our Unite Austin 2017 YouTube playlist to catch up on what you missed. More videos coming soon.
    Dismiss Notice
  2. Unity 2017.2 is now released.
    Dismiss Notice
  3. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  6. Unity 2017.3 beta is now available for download.
    Dismiss Notice

Assets [WIP] Odin Inspector & Serializer Looking for Feedback

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

  1. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    473
    I heard the asset was already sent to the Unity Asset Store review system :)
     
  2. roykoma

    roykoma

    Joined:
    Dec 9, 2016
    Posts:
    36
    MaDDoX, Tor-Vestergaard and MrG like this.
  3. SuneT

    SuneT

    Joined:
    Feb 29, 2016
    Posts:
    41
    Yes, it is official! Odin is finally here.

    Thank you so much to the Unity Asset Store team for approving Odin :)
    We (Devdog and Sirenix) look very much forward to hearing what you think about Odin. We've been working super hard on it for the past 10-11 months now.
     
  4. Landiron

    Landiron

    Joined:
    May 8, 2013
    Posts:
    5
    Congrats, looks good from what I saw so far. ;)

    I might have missed it in the manual, but how can I display Dictionaries with custom classes in the inspector ?

    public Dictionary<enum, customClass> Dictionary = new Dictionary<enum, customClass>();

    wont show up for me in the inspector.
     
  5. Samuel411

    Samuel411

    Joined:
    Dec 20, 2012
    Posts:
    599
    :D :D :D I bought it, I'll be playing with this for the next few weeks and i'll write up a review on the asset store. Love you. Saving me tons of time from making custom editors for smaller things.
     
    bjarkeck and jorisshh like this.
  6. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    473
    Will I only be able to create custom inspectors for my personal projects? Or could I create a custom inspector for an asset of mine?
     
  7. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    76
    There are a couple of ways to show dictionaries in the editor. The first one is to inherit from SerializedMonoBehaviour.
    This means that the public dictionary field will be serialized, and Odin will, therefore, include the property in the inspector.

    Another way is to add the [ShowInInspector] attribute to the field. However, then you will need to handle serialization yourself if you need it.

    There is also the [ShowOdinSerializedPropertiesInInspector] which you can put on your MonoBehaviour class or base-class. This will mark a type as being specially serialized. Odin uses this attribute to check whether it should include non-Unity-serialized members in the inspector.

    Odin will serialize any dictionary, and the inspector does not care what types the values are. But for the dictionary key type, we currently only support primitive types such as string, char, byte, int etc... However, enums is actually one of those types we could add support for in the future.
     
    Last edited: May 12, 2017
    Samuel411 likes this.
  8. Samuel411

    Samuel411

    Joined:
    Dec 20, 2012
    Posts:
    599
  9. roykoma

    roykoma

    Joined:
    Dec 9, 2016
    Posts:
    36
    bjarkeck likes this.
  10. MaDDoX

    MaDDoX

    Joined:
    Nov 10, 2009
    Posts:
    749
    Very nice, I've been waiting for someone to (try to) tackle the slowness of custom serialization. I've been a dedicated tester of VFW and followed its serialization woes and breakages at each new Unity version release until the developer finally threw the towel and deprecated custom serialization. So, some questions before I purchase this in hope that it is the holy grail we've been searching for:

    - I've seen you got horizontal layout options, excellent - but how do you define the width of each horizontal section?
    - Can you define the width of key and value columns in the dictionaries inspector? Do you have settings like "Auto width", "x% width", "pixel width"? This is critical for the proper display of different dictionary KVP combinations.
    - As for your custom binary serialization, how 'shielded' from Unity's several API changes at each new release do you expect Odin to be? FullInspector and others have had a tough time with Unity upgrades breaking their deserialization process.
    - How fast is your custom binary serialization when compared to Unity's ridiculously limited yet blazing fast serialization?
    - Can you use Odin styling for EditorWindows?
    - Inlining by itself is a must-have, killer feature, I've done editor inlining manually and am pretty aware how painful it is to do it without a helper. Does your inlining implementation support Scriptable Assets?
    - Can your custom serialization work with non-MonoBehaviours, like StateMachineBehaviour for instance? I saw you have an attribute for class serialization, not sure if it works for this.
     
    Last edited: May 12, 2017
  11. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    Odin declares its presence in a project by adding the "ODIN_INSPECTOR" compiler define tag. So if you wish to add Odin support to your asset, you can wrap the Odin parts of them in with #if ODIN_INSPECTOR statements. That way, they'll activate if Odin is present in the project.

    Woah, that's a lot of questions. I'll go through them one by one.

    HorizontalGroup was actually pulled as a feature before release, because it wasn't working right as intended, and implementing it properly in a solid and reliable way turned out to be - surprisingly - trickier than expected. We decided to focus on reaching a solid level of polish before release. However, sometime in the near future we will revisit this property group type, and at that time, there will definitely be support for adjusting the width of individual properties in the group, both via percentages and fixed pixel sizes.

    At the moment, no, as you currently can't apply custom attributes (and thus custom layouting) to the keys and values of dictionaries themselves. However, we have a plans for enabling properties to "inherit" attributes from their parent properties, and in this way, you would be able to adjust the dictionary to your liking. Otherwise we'd need to custom code a case specifically for dictionaries, and we haven't done that yet.

    Odin's serialization is minimally reliant on Unity itself. In fact, it was written as a completely stand-alone serialization system before Unity support was even added as an extension on the core system. The serialization and deserialization, for the most part, is not actually aware that it is running in Unity. Unity would have to make changes to core APIs (such as the ISerializationCallbackReceiver interface) or break their own serialization somehow before ours broke. Of course, this hasn't stood the test of time, but as far as we can tell, the base serialization should be rock solid in terms of the Unity API.

    However, there is one (peripheral) part of serialization that relies more on the Unity API than the rest, and therefore it is the most fragile part of serialization. This is the prefab instance modification system for Odin-serialized data. However, so far there have been no known version or API-related issues with it across all versions we've tested Odin on, and it's worked fine. I'm more hesitant to make strong claims here, but again, this should be solid unless Unity makes some very drastic changes.

    It's not quite as fast as Unity's, as using it in Unity does necessarily mean serializing to a byte array, which Unity can then serialize. That said, it is quite fast, and you should see barely any performance hit from it in builds. In most cases, serializing using the binary format will allocate no garbage at all, and deserializing will allocate only the metadata strings necessary for associating values with members. This is not counting allocation of memory streams.

    We use a lot of techniques such as emitting custom-tailored formatters for types to avoid reflection (on platforms where this is possible), as well things like memory copying and unsafe pointer-level editing of strings, in order to minimize heap allocations and speed up the serialization as much as we reasonably can while keeping all of its features (support for polymorphism and cyclical references, no attribute annotations required, high tolerance for data types and metadata names changing under its feet, as well as a high degree of extensibility). From the comparison tests we've run (admittedly from at least half a year ago, and merely what I recall from memory) it's comparable to other libraries known for being fast, such as ProtoBuf.NET.

    Serialization was the first part of Odin we built. Frankly, we haven't touched it that much in quite a while, which is probably a good sign.

    You can - though you do need to write a tiny amount of code for it. You can create an Odin property tree (our version of Unity's "SerializedObject") for any set of objects (even non-UnityEngine.Object derived types) - so in this case you could create a property tree to inspect your window instance, and then draw that.

    [​IMG]

    Of course, you also have free access to our entire editor drawing API (most notably GUIHelper and SirenixEditorGUI), which makes it very easy to draw Odin-style UIs with your own custom code.

    Yes, it does. Our inlining supports anything that can be shown in the inspector by Unity, as we literally create a new Unity editor instance and render that inline. The only exception would be GameObject values, where we do not currently render all components - only a visual preview of the GameObject mesh itself. However, eventually even that will be supported.

    We support all commonly-derived Unity types. This includes UnityEngine.Object, Component, Behaviour, MonoBehaviour, ScriptableObject and StateMachineBehaviour. It is also trivial to add support for your own type, if you do not wish to derive from these for some reason.

    I hope that answers all of your questions satisfactorily!
     
    alexanderameye, MaDDoX and bjarkeck like this.
  12. MaDDoX

    MaDDoX

    Joined:
    Nov 10, 2009
    Posts:
    749
    Yeah, I seriously doubt "inheriting" width from a property would work in that case, since key and value fields are side by side you need fine control on how much of each you want to show for maximum legibility / ease of use. Besides, although it's comprehensibly not a top priority, let me reiterate the need for proper horizontal layout features. For the best possible usage of space, I extensively use horizontal stacking of smaller fields. For us to get completely rid of the necessity of creating our own editors, having horizontal groups would be the only way.

    I must say that's extremely impressive my dear sir :) Also, docs are very elegant and readable, great job on that. I'm satisfied, you got a sale!
     
  13. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    25
    purchased one, realy nice asset !
     
  14. MaddoScientisto

    MaddoScientisto

    Joined:
    Jan 30, 2015
    Posts:
    59
    I just purchased this but as soon as I imported I got the following error whenever code is recompiled:

    C:\dev\unity\ProjectMercury\Temp\CodeGeneration-43fc1341-681c-4876-a509-222898726016\Drawers.cs(958,25): error CS0101: The namespace `Sirenix.OdinInspector.GeneratedEditors' already contains a definition for `FlyingWormConsole3_ConsoleProRemoteServer_Editor'
    UnityEngine.Debug:LogError(Object)
    Sirenix.Utilities.Editor.CodeGeneration.AssemblyGenerator:Compile(String, Boolean) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Utilities.Editor/Code Generation/AssemblyGenerator.cs:374)
    Sirenix.OdinInspector.Editor.EditorCompilation:CompileEditors(TypeDrawerPair[]) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:396)
    Sirenix.OdinInspector.Editor.EditorCompilation:TriggerAutomaticRecompile(TypeDrawerPair[]) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:299)
    Sirenix.OdinInspector.Editor.EditorCompilation:RecompileAsSoonAsPossibleForMissingTypes() (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:290)
    UnityEditor.EditorApplication:Internal_CallUpdateFunctions()

    Which is pretty weird, it's probably conflicting with Console Pro 3 but it's weird

    EDIT: Disabling that specific plugin in the preferences (which I didn't know existed because I didn't read the docs yet) seems to have fixed it
     
    Last edited: May 13, 2017
  15. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    Yeah, this would have been because multiple types with the same full names (namespace plus type name) were loaded. In this case, likely the "FlyingWormConsole3.ConsoleProRemoteServer" type was declared several times, spread across different assemblies. This happens when we compile our custom editors, and the compiler can't determine which of the two types with the same full name we're talking about in the source code.

    Therefore, we don't support such type naming conflicts right now, and we're not entirely sure we will, as the solution we'd have to implement might be worse than the problem it would fix. As you discovered, fixing it is rather easy, simply by disabling the generation of an editor for one of the conflicting types in question.

    That said, we should probably give better error feedback in the inspector when this happens.
     
  16. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    76
    Hi MaDDoX,

    We'll include the HorizontalGroup attribute in the next patch again. Here quick screenshot of it in action, let me know if you have any feature requests or suggestions for it!

    Horizontal Group Attribute.png
     
    Samuel411 likes this.
  17. Samuel411

    Samuel411

    Joined:
    Dec 20, 2012
    Posts:
    599
    Can't wait for unity to pass through the update, I'm loving this asset, saved me so much time.
     
    bjarkeck likes this.
  18. garraeth

    garraeth

    Joined:
    Apr 20, 2014
    Posts:
    7
    Just purchased and am getting the same errors as: https://forum.unity3d.com/threads/w...oking-for-feedback.457670/page-2#post-3068214

    I don't have "Console Pro 3".

    I tried disabling plugins (in Unity: Window->Odin Inspector->Preferences->Editor Types->Plugin Types, unchecking all the checkboxes).
    In the "Editor Types"->"Plugin Types" I only have Facebook and Sirenix (yours I presume) as parent nodes.

    I can uncheck any combo (of either parent(s) or any children), hit the "Recompile Editors"...it chugs along w/ no errors. Then I run my app and get the warnings and error again. And when I go back to Editor Types in the Odin Inspector, the checkboxes are all checked again (doesn't seem to have saved my settings).

    From the error, it looks like it's Facebook - but since the preferences don't seem to be saving....it's not ignoring the FB plugin.

    Can Odin run with these errors? Please let me know because in the mean time I'm going to remove it...but if it'll still run w/ these errors, I'll just ignore them for now since I know the Unity approval process can take days.

    Thx!

    First warning is:
    The following 1 errors occurred while compiling a generated assembly at '[my path]/Assets/plugins/Sirenix/Assemblies/Editor/GeneratedOdinEditors.dll':
    UnityEngine.Debug:LogWarning(Object)
    Sirenix.Utilities.Editor.CodeGeneration.AssemblyGenerator:Compile(String, Boolean) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Utilities.Editor/Code Generation/AssemblyGenerator.cs:365)
    Sirenix.OdinInspector.Editor.EditorCompilation:CompileEditors(TypeDrawerPair[]) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:396)
    Sirenix.OdinInspector.Editor.EditorCompilation:TriggerAutomaticRecompile(TypeDrawerPair[]) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:299)
    Sirenix.OdinInspector.Editor.EditorCompilation:RecompileAsSoonAsPossibleIfEditorsChanged() (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:247)
    UnityEditor.EditorApplication:Internal_CallUpdateFunctions()


    Second warning is:
    ( You can view the faulty source code files at the path '[my path]\Temp\CodeGeneration-f043d017-0fcb-4bc4-ad24-c53b64732e9e\'. They will remain until Unity is restarted. )
    UnityEngine.Debug:LogWarning(Object)
    Sirenix.Utilities.Editor.CodeGeneration.AssemblyGenerator:Compile(String, Boolean) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.Utilities.Editor/Code Generation/AssemblyGenerator.cs:369)
    Sirenix.OdinInspector.Editor.EditorCompilation:CompileEditors(TypeDrawerPair[]) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:396)
    Sirenix.OdinInspector.Editor.EditorCompilation:TriggerAutomaticRecompile(TypeDrawerPair[]) (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:299)
    Sirenix.OdinInspector.Editor.EditorCompilation:RecompileAsSoonAsPossibleIfEditorsChanged() (at C:/Users/Bjarke/Desktop/Projects/Sirenix Development Framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/EditorCompilation.cs:247)
    UnityEditor.EditorApplication:Internal_CallUpdateFunctions()


    Error is:
    [my path]\Temp\CodeGeneration-f043d017-0fcb-4bc4-ad24-c53b64732e9e\Drawers.cs(1158,25): error CS0101: The namespace `Sirenix.OdinInspector.GeneratedEditors' already contains a definition for `Facebook_Unity_FB_Editor'
    0x000000014179D92B (Unity) StackWalker::GetCurrentCallstack
    0x000000014179F5DF (Unity) StackWalker::ShowCallstack
    0x00000001417796A0 (Unity) GetStacktrace
    0x0000000140D3F23B (Unity) DebugStringToFile
    0x0000000140D3FA1C (Unity) DebugStringToFile
    0x00000001413FE562 (Unity) DebugLogHandler_CUSTOM_Internal_Log
    0x000000003BF633AB (Mono JIT Code) (wrapper managed-to-native) UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,string,UnityEngine.Object)
    0x000000003BF63294 (Mono JIT Code) [DebugLogHandler.cs:9] UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
    0x000000003BF62C25 (Mono JIT Code) [Logger.cs:41] UnityEngine.Logger:Log (UnityEngine.LogType,object)
    0x00000000404B6803 (Mono JIT Code) [DebugBindings.gen.cs:124] UnityEngine.Debug:LogError (object)
    0x0000000040492383 (Mono JIT Code) [AssemblyGenerator.cs:374] Sirenix.Utilities.Editor.CodeGeneration.AssemblyGenerator:Compile (string,bool)
    0x000000004047D67B (Mono JIT Code) [EditorCompilation.cs:396] Sirenix.OdinInspector.Editor.EditorCompilation:CompileEditors (Sirenix.OdinInspector.Editor.TypeDrawerPair[])
    0x000000004047C0AA (Mono JIT Code) [EditorCompilation.cs:299] Sirenix.OdinInspector.Editor.EditorCompilation:TriggerAutomaticRecompile (Sirenix.OdinInspector.Editor.TypeDrawerPair[])
    0x00000000404595F6 (Mono JIT Code) [EditorCompilation.cs:247] Sirenix.OdinInspector.Editor.EditorCompilation:RecompileAsSoonAsPossibleIfEditorsChanged ()
    0x00000000404578E4 (Mono JIT Code) (wrapper delegate-invoke) UnityEditor.EditorApplication/CallbackFunction:invoke_void__this__ ()
    0x000000004045782C (Mono JIT Code) (wrapper delegate-invoke) UnityEditor.EditorApplication/CallbackFunction:invoke_void__this__ ()
    0x000000004045782C (Mono JIT Code) (wrapper delegate-invoke) UnityEditor.EditorApplication/CallbackFunction:invoke_void__this__ ()
    0x0000000040459009 (Mono JIT Code) [EditorApplicationBindings.gen.cs:249] UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()
    0x00000000006D11DE (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void (object,intptr,intptr,intptr)
    0x00007FFEADD35703 (mono) [mini.c:4937] mono_jit_runtime_invoke
    0x00007FFEADC88425 (mono) [object.c:2623] mono_runtime_invoke
    0x00000001401A8723 (Unity) mono_runtime_invoke_profiled
    0x000000014105B58B (Unity) CallStaticMonoMethod
    0x000000014105D907 (Unity) CallStaticMonoMethod
    0x0000000141723666 (Unity) Application::TickTimer
    0x00000001417EEA1C (Unity) CrashCallback
    0x00000001417F0664 (Unity) WinMain
    0x0000000141AD38E4 (Unity) strnlen
    0x00007FFECFBC8364 (KERNEL32) BaseThreadInitThunk
    0x00007FFED06370D1 (ntdll) RtlUserThreadStart
     
  19. Owlglass_Moot

    Owlglass_Moot

    Joined:
    Jan 4, 2015
    Posts:
    9
    Just bought this and I'm liking it quite a bit!

    Are there any plans to allow Enums as Dictionary keys?

    Also, is there any way to change the name at the top of an object's foldout box to display the object's ToString() method rather than the name of the variable?

    For example:
    Code (CSharp):
    1. using UnityEngine;
    2. using Sirenix.OdinInspector;
    3.  
    4. [System.Serializable]
    5. public class Person
    6. {
    7.    [ShowInInspector] string firstName;
    8.    [ShowInInspector] string lastName;
    9.  
    10.    public override string ToString()
    11.    {
    12.       return string.Format("{0} {1}", firstName, lastName);
    13.    }
    14. }
    15.  
    16. public class BlahBlahBlah : MonoBehaviour
    17. {
    18.    [ShowInInspector] Person myPerson;
    19. }
    [​IMG]

    Like is it possible to replace "My Person" with "Festus Kreely"?
     
    Last edited: May 14, 2017
  20. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    76
    A little warning just in case: [ShowInInspector] does not mark your fields for serialization so they will not be saved. You either need to mark them with [SerializeField] or make them public. There is also the [OdinSerialize] attribute, but that is only meant to be used for auto-properties and other special cases.

    Love your request btw, and yes something like this is possible!
    Test.png

    We also have the [LabelText("")] attribute, which we also could add support for referencing a member like.
     
    Owlglass_Moot likes this.
  21. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    25
    he i found a small problem with document.
    http://www.sirenix.net/odininspector/documentation/sirenix/odininspector/showifattribute
    hideif or etc...
    if function check condition show attribute is "private function", it will not working if this "function check condition" in parent class, and you serialize a extend class.
    In my case i have a abstract class and serialize a list of this abstract class.
    just change to protected or publish function.
     
  22. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    We should have resolved this issue in the next patch. The error won't happen any more and editor compilation will succeed. However, we won't generate editors for any types with conflicting full names. Instead, you'll get a warning that tells you which assemblies the conflicting types (if any) were declared in, and they will be automatically disabled in the preferences for next time. You can also disable the warning in the preferences, should you so wish.

    The patch should be submitted sometime today, and after that it just needs to get through asset store approval before you'll get it.

    I'm not quite sure what the issue is - we do support private functions in base classes for that attribute, and a test I just ran seems to confirm that it works. Could you write a code example that showcases the problem in question?
     
  23. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    25
    if IsInteractByButton fuction is private it will not work. And i read a warning on Inspector. Dont have any reflection on standalone platform, what about mobile platform?

    Code (CSharp):
    1. [System.Serializable]
    2. public abstract class A
    3. {
    4.     [ShowIf("IsInteractByButton")]
    5.     [SerializeField]
    6.     protected KeyCode m_InputName;
    7.  
    8.     protected bool IsInteractByButton()
    9.     {
    10.         return true;
    11.     }
    12. }
    13.  
    14. public class B: A
    15. {
    16.  
    17. }
    18.  
    19. public class AController : SerializedMonoBehaviour
    20. {
    21.     public List<A> listAbility = new List<A>();
    22. }
     
    Last edited: May 14, 2017
  24. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    76
    Thanks! It's fixed now, and will work in the next path.
     
  25. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    2,282
    I've been looking for a better inspector for a while. I have a competing product, but it's problematic. One thing I don't like about the other product is that it automatically uses it's own version of the Inspector for everything by default, which is undesirable in most cases. I actually have to go into scripts and add code to tell it to not use the fancy inspector. And it basically hijacks the entire project so if I remove the advanced inspector, it has lingering effects that are hard to fix. I want to know if Odin is anything like that. I'd rather only use Odin in special cases where needed and not have it take over my project. Thanks for any information you can provide.
     
  26. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    25
    i purchased one and i see only list and array serialize is not default. It's better

    Other question, i see a warning on Inspector: "Dont have any reflection on standalone platform", what about mobile platform? I really need optimize on mobile.
     
  27. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    76
    Hi magique.

    First off, you have full control over what Odin should or shouldn't draw. You can disable Odin for specific scripts, entire name-spaces or assemblies: And if we find that some of your types already have a custom editor script, we don't touch it.

    Config.png

    We do upgrade some of the existing editors just like other inspectors out there, but we try to stay as clean and familiar as possible. For instance, if you simply drop Odin into your project and don't do anything else, you will see that your editors in the inspector will look the same as they did before, except for some obvious stuff like lists. But now object-field pickers will have an extra little button that will open the object in a new inspector window. Vectors can now be scaled by dragging on the label, and you have a lot more right-click context menu options. Small stuff like that..

    Also, as you properly know, Odin works without inheriting from any base-class. So this means that you can use Odin ONLY to customizing the look of what Unity already knows how to draw. The SerializableMonoBehaviour is only there for you if you want to serialize and show data that Unity can't serialize. If you decide to not to use the Odin serialization stuff, Odin won't touch your game-code ever. And if you should upgrade to a new Unity release which Odin doen't yet support or something, we've made sure that all of the attributes is in its own dll, so you can simply delete Odin except for the attirbutes dll, and you can continue with your project and wait until we patch it.
     
    Last edited: May 14, 2017
  28. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    2,282
    Thanks @bjarkeck. That sounds better than the inspector I had tried before.
     
  29. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    For now, we do use reflection on mobile when we serialize and deserialize, which means you may see some performance problems if you use our custom serialization very heavily. We're going to improve on this fairly soon and add features that let users eliminate the use of reflection completely, but meanwhile people on mobile should make particular efforts to limit how much and where they use Odin's serialization.

    Using it on manager objects that only spawn once is probably fine, while having a lot of data on objects that spawn constantly may not be a great idea - in the end, you can profile how well it runs for your particular case and determine what to do from there.

    And if course, if you don't use our custom serialization, you won't see any performance difference at all.
     
  30. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    25
    So, reflection will cache once on Awake and i can call it alway on Update ?. It's good enought for me.
     
  31. Owlglass_Moot

    Owlglass_Moot

    Joined:
    Jan 4, 2015
    Posts:
    9
    Thanks so much!
     
  32. SuneT

    SuneT

    Joined:
    Feb 29, 2016
    Posts:
    41
    We just submitted version 1.0.0.3 Odin yesterday - awaiting Unity approval right now.

    Here's what has changed. Keep the feedback coming, as we continue improving Odin :)

    Highlights
    • HorizontalGroup attribute has been added. Checkout it out in the updated demo scene.
    • Odin now works in the latest Unity 2017 beta version.
    • Assembly documentation xml files are now included in the package. This means the api documentation now will show up in the IntelliSense.
    • Odin now works much better with external plugins. It now handles duplicate type name conflicts during editor generation far more gracefully, giving detailed warning messages (which can be disabled), and automatically disabling editor generation for the types in question to fix the error.
    Fixes
    • Fixed an error where private members in base-classes would by be found by attributes such as ShowIf and HideIf.
    • Fixed various errors that broke everything in the 2017.1 beta. NOTE: To fix errors in the 2017.1 beta, a feature has been disabled since an error was introduced by Unity that prevents it from working. The feature in question is drawing custom Unity Property Drawers for data which is not serialized by Unity. If an attribute seems to have no effect in 2017.1, it is likely because it was implemented by a custom Unity Property Drawer and the data is not being serialized by Unity.
    • Fixed a bug where you couldn't put several [CustomContextMenu] on a property and have them all show up in the context menu.
    • The Header and Title attributes are now part of the super drawer queue, which means they no will longer be indented by the attribute as originally intended.
    • Fixed a lot of spacing inconsistencies between GUI Elements.
    • Fixed a bug where the ValidateInput attribute would break if the type was changed.
    • Fixed a bug where set-to-null did not work on Nullable<T> types.
    • The Space attribute will no longer be applied to List elements.
    • Fixed a bug where GUILayoutOptions.MaxWidth() specified the width instead of the MaxWidth.
    • Fixed TabGroup GUI popping issues.
    • Fixed an issue where EnumDrawer would not apply changes to the property.
    Changes
    • Build serialization format can now only be set to data formats valid in builds.
    • Whether or not a property tree should draw the mono-script object field at the top, can now be specified via the new myPropertyTree.DrawMonoScriptObjectField property.
    Upgrade Notes
    • Delete Sirenix/Odin Inspector/Demo folder
    • Import new package.
    • Delete Sirenix/Assemblies/Editor/GeneratedOdinEditors.dll after upgrading, which will cause it to regenerate an updated version of itself if you have this behaviour enabled. The old .dll may cause a multitude of Mono.Cecil type lookup errors to be generated in the console. (These messages are harmless, but annoying.)
     
    Last edited: May 15, 2017
    alexanderameye likes this.
  33. Owlglass_Moot

    Owlglass_Moot

    Joined:
    Jan 4, 2015
    Posts:
    9
    I may have found a slight bug? Or maybe it's WAD or I'm doing something wrong, I dunno.

    Code (CSharp):
    1. [ShowOdinSerializedPropertiesInInspector]
    2. public abstract class MyMonoBehaviour : SerializedMonoBehaviour { }
    3.  
    4. public class SomethingStrange : MyMonoBehaviour { }
    I have an empty scene, nothing but the Main Camera and the GameObject containing the SomethingStrange component. It seems that if the scene is playing and I hit stop while having SomethingStrange selected and visible in the inspector, it sets the scene to dirty, as if it needs saving. It does this even if I save right before hitting play.
     
  34. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    76
    That is something strange indeed! And it seems that:

    Code (CSharp):
    1. public class SomethingStrange : SerializedMonoBehaviour
    2. {
    3. }
    Actually is enough to trigger it. I'm looking in to it.

    As a side note [ShowOdinSerializedPropertiesInInspector] is actually only needed if you are not inheriting SerializedMonoBehaviour but you want Odin to act as if you where. And remember, you only need to inherit from SerializedMonoBehaviour if you want to serialize stuff that otherwise would not be serialized by Unity :)
     
  35. MaddoScientisto

    MaddoScientisto

    Joined:
    Jan 30, 2015
    Posts:
    59
    If I make a custom editor on top of an object that has Odin attributes such as [Readonly] and then in the editor I use
    DrawDefaultInspector() then any Odin attributes will not render at all the way they are supposed to, for instance the readonly attributes will not be read only.
    Is there a way to retain them while still having a custom editor?
    I need the custom editor because I need to call some editor windows that aren't available in non-editor scripts, so I'm forced to make buttons for them in custom editors.
     
    Last edited: May 16, 2017
  36. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    A quick heads up for anybody who installed the latest patch (1.0.0.3).

    A bug was accidentally introduced in this patch, which causes public members marked with [NonSerialized] to show up in the inspector. This is particularly visible on asset lists, which show a lot of properties which were previously hidden. A patch with a fix for this has already been submitted and is undergoing approval.

    Meanwhile, while the bug may be annoying, it is entirely harmless. Remember, if any of your members show up despite being marked as [NonSerialized], you can make sure it is hidden by decorating it with the [HideInInspector] attribute.

    Note that this only affects what is shown in the inspector, not what is actually serialized.
     
  37. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    You can derive your custom editor from the OdinEditor class, override OnInspectorGUI, and then to draw the "default" Odin editor, call base.OnInspectorGUI().
     
    MaddoScientisto likes this.
  38. MaddoScientisto

    MaddoScientisto

    Joined:
    Jan 30, 2015
    Posts:
    59
    Thank you, That did the trick!

    I hope the documentation gets completed soon, there's so much that can be done but I have no idea that can be done yet.
     
  39. Zionmoose

    Zionmoose

    Joined:
    Oct 17, 2012
    Posts:
    223
    Hello. I submitted an email but figured I would post here as well for extra viability. I have found 2 issues myself.

    I am currently running unity 5.6.0f3 and this can be replicated by just importing Odin into a new, blank project.

    Issue 1: Trying to open the About Unity page under the help menu cause a lot of errors and the screen is just black. Image below.
    Issue 2: Several of the list manipulation button icons stop drawing when you change scenes. I was viewing your own demo scenes that come with the project. When I open Unity, it appears there is no issue when looking at a list in one of your scenes. All icons are present on the buttons. But if you switch scenes, and look at an inspector list, you will notice icons are missing. And if you switch scenes again, more icons go missing. Only way to get them to show again is restart unity. Image below.

    Other than those issues things are looking great.

    image.png

    image (1).png
     
  40. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    We've just committed fixes to both of these issues to our repository - they will make it into the patch after 1.0.0.3a.

    No problem! And yes, we definitely do need to finish that documentation. However, for now we've chosen to prioritize bug-fixing, until we have a proper handle on all that. Luckily, it seems we're getting there, so hopefully we can continue work on the documentation very soon.
     
    MaddoScientisto likes this.
  41. Froghuto

    Froghuto

    Joined:
    Oct 4, 2012
    Posts:
    39
    We just bought Odin and it's really great! But I think we found a bug.
    We generate assets (Meshes etc) and put them into SerializableObject's with AssetDatabase.AddObjectToAsset(). We then put references to those assets into "[SerializeField] private" fields inside that SerializableObject. When viewing those SerializableObjects in the Inspector with Odin enabled the references to those local assets get lost. When disabling Odin editor for that specific type (so using native Unity Inspector) the references are saved and preserved.
     
  42. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    Thanks for the report - we're looking into it!
     
  43. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    So I've been trying to replicate this in 5.3.0 and 5.6.1, and so far I haven't been able to make it break.

    This is my testing code:

    Code (CSharp):
    1.  
    2. using Sirenix.OdinInspector;
    3. using System.Linq;
    4. using UnityEditor;
    5. using UnityEngine;
    6.  
    7. [CreateAssetMenu(fileName = "Test", menuName = "Test/Create", order = -10000)]
    8. public class NewScriptableObject : SerializedScriptableObject // Also tried with just deriving from ScriptableObject, it made no difference
    9. {
    10.     [SerializeField]
    11.     private Mesh testMesh;
    12.  
    13.     [SerializeField]
    14.     private Mesh[] allMeshes;
    15.  
    16.     [Button]
    17.     private void CreateSubAsset()
    18.     {
    19.         this.allMeshes = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(this)).OfType<Mesh>().ToArray();
    20.  
    21.         Mesh mesh = new Mesh();
    22.         mesh.name = "TestMesh_" + this.allMeshes.Length;
    23.  
    24.         mesh.vertices = new Vector3[]
    25.         {
    26.             Vector3.up,
    27.             Vector3.left + Vector3.up,
    28.             Vector3.left,
    29.             Vector3.zero,
    30.         };
    31.  
    32.         mesh.triangles = new int[]
    33.         {
    34.             0, 1, 3,
    35.             1, 2, 3,
    36.         };
    37.  
    38.         mesh.RecalculateNormals();
    39.         mesh.UploadMeshData(false);
    40.  
    41.         AssetDatabase.AddObjectToAsset(mesh, this);
    42.         this.testMesh = mesh;
    43.     }
    44. }
    45.  
    And this is the result:

    [​IMG]

    I've tried reloading the project, moving the asset around, messing with the values. So far, nothing I've done has broken any of the mesh references. Can you perchance post (or PM) me the code that has the issue, or tell me whether my test code above is insufficient?
     
    Last edited: May 17, 2017
  44. Froghuto

    Froghuto

    Joined:
    Oct 4, 2012
    Posts:
    39
    Now that I looked at it it seems that it works for meshes, but other assets (I tried Materials and Texture2Ds) don't.
    Sorry for my bad reporting skills :/
     
  45. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    That did it! I managed to replicate this issue, and a fix is making it into the next patch, 1.0.1. I'll PM you a link to a temporary build with a lot of the latest fixes, since asset store approval takes a while to come through.
     
    Froghuto likes this.
  46. Froghuto

    Froghuto

    Joined:
    Oct 4, 2012
    Posts:
    39
    Thanks for the super fast support!
    I'll just leave my wishlist for future features here... :)
    - More / any types for Dictionary keys
    - Copy&Paste values in Inspector windows using a hotkey and drag&drop
     
  47. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    25
    anyone know it ?
     
  48. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    Serialization happens when a prefab is instantiated, and deserialization happens when an object is loaded (IE, when a scene or resource asset is loaded) or a prefab is instantiated. So it is at these times that reflection is used by Odin on mobile, for objects that are derived from SerializedMonoBehaviour, SerializedScriptableObject, etc.

    Nothing happens in Awake, Start, or other such methods - Odin uses the ISerializationCallbackReceiver interface to determine when data should be serialized and deserialized. As a rule, deserialization happens before Awake or any other Unity event methods are ever called on your object.

    Generally speaking, loading scenes and instantiating prefabs are already very expensive operations on mobile that people tend to avoid, so in truth Odin shouldn't make that much of a difference. It will generally only make a difference if you are making Odin serialize very large amounts of data.
     
    DungDajHjep likes this.
  49. dizzy2003

    dizzy2003

    Joined:
    Nov 25, 2013
    Posts:
    9
    Feature Request.

    I often have an enum and a matching list eg:

    enum Things
    {cat,dog,cow,max};

    public List<GameObject> m_Things[Things.max];

    so I'd like to be able to create a list with each item in the list labeled with the enum type

    So the user can see they need a cat like object dragged into element 0 a dog like object in element 1 etc.

    I didnt see anything obvious in the demos to show this might be all ready possible.

    so an annotaion like
    [ListLabels("Things")]
     
    Sirenix likes this.
  50. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    123
    We haven't written the drawers 101 section yet, so it would be unclear how to do this, but it is quite easy to create your own attribute that does exactly this. Here's how.

    Say you declare an attribute like this:

    Code (CSharp):
    1. using System;
    2.  
    3. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
    4. public class EnumListLabelAttribute : Attribute
    5. {
    6.     public Type EnumType;
    7.     public float LabelWidth;
    8.  
    9.     public EnumListLabelAttribute(Type enumType, float labelWidth)
    10.     {
    11.         this.EnumType = enumType;
    12.         this.LabelWidth = labelWidth;
    13.     }
    14. }
    And then, in an editor script (located in an editor folder), declare this drawer:

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using System.Collections;
    4. using Sirenix.OdinInspector.Editor;
    5. using Sirenix.Utilities.Editor;
    6.  
    7. [OdinDrawer]
    8. [DrawerPriority(0, 1000, 0)] // Set a high wrapper priority, so the drawer is part of the wrapping queue
    9. public class EnumListLabelDrawer : OdinAttributeDrawer<EnumListLabelAttribute>
    10. {
    11.     public override bool CanDrawTypeFilter(Type type)
    12.     {
    13.         return !typeof(IList).IsAssignableFrom(type); // Don't draw for the list itself, only the list elements
    14.     }
    15.  
    16.     protected override void DrawPropertyLayout(InspectorProperty property, EnumListLabelAttribute attribute, GUIContent label)
    17.     {
    18.         // Get label for enum index
    19.         int index = property.Index;
    20.         string indexName = Enum.GetNames(attribute.EnumType)[index];
    21.  
    22.         // Set label width
    23.         GUIHelper.PushLabelWidth(attribute.LabelWidth);
    24.         {
    25.             // Call next drawer with enum entry
    26.             this.CallNextDrawer(property, new GUIContent(indexName));
    27.         }
    28.         GUIHelper.PopLabelWidth();
    29.     }
    30. }
    Now, you can easily decorate your list with this attribute, like so:

    Code (CSharp):
    1. [EnumListLabel(typeof(Things), 50)]
    2. public GameObject[] m_Things = new GameObject[(int)Things.max];
    And this will be the result:

    [​IMG]
     
    Last edited: May 18, 2017
    Polymo and Sirenix like this.