Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

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

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

  1. jorisshh

    jorisshh

    Joined:
    Oct 6, 2009
    Posts:
    1,512
    Odin v. 1.0.6 is now live - go update if you haven't already. There are some real treats in there ;)

    In fact, here's a quick overview of just a few of the improvements available in the latest update:


    You can find the full patch notes right here - I really encourage you to especially try playing around with the new fancy Odin Editor Windows!

    What do you think about the latest update? Be sure to let us know here or even better; on our Discord server.
     
    Peter77, bjarkeck and Infrid like this.
  2. Infrid

    Infrid

    Joined:
    Jan 14, 2012
    Posts:
    67
    My #1 best asset store purchase of all time. You never cease to amaze me. Thanks! btw - your support page on your site is gorgeous - I just shared it with some designer colleagues ;)
     
    bjarkeck likes this.
  3. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Thanks for the feedback! We'll keep improving the documentation, and the onboarding experience. We also really want to make a manual for editor windows, and showing various ways you can use it to enhance your workflow. But that will most likely come at the end of the 1.0.6.x cycle as there are still a few features in the works that we want to include.

    We also just implemented the getting started popup guide. Which we'll also keep improve upon and add more good examples in there.

    I'm not entirely sure what you mean by this, I'm not familiar with BestHTTP. Is it that you want Odin to draw some of BestHTTP's types that they've not included? If so, I would look into making custom value drawers with Odin.


    Don't know exactly why you think you need the OnValueChanged attribute? You can just remove that. The field should be rendered just fine on its own without any attributes.
     
  4. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    910
    Thanks for the responses man.
    when i do using BestHTTP with the rest of the directives it tells me it doesn't exist.
    Or maybe i just need to do my web requests using BestHTTP on another script and call that function from in side your wrapper.

    So I guess my question is how do I call a function on a mono behavior script from inside my class?

    Im wanting to run a meathod when my CreateQuest button is hit.

    Code (csharp):
    1. using UnityEditor;
    2. using Sirenix.OdinInspector.Editor;
    3. using Sirenix.OdinInspector;
    4. using UnityEngine;
    5. using Sirenix.Utilities.Editor;
    6. using Sirenix.Utilities;
    7.  
    8.     public class QuestCreator : OdinEditorWindow
    9.     {
    10.         [MenuItem("Game Tools/Quest Creator")]
    11.         private static void OpenWindow(){
    12.             var window = GetWindow<QuestCreator>();
    13.             window.position = GUIHelper.GetEditorWindowRect().AlignCenter(500, 500);
    14.         }
    15.         public string QuestName;
    16.         [Button(ButtonSizes.Large), GUIColor(0, 1, 0)]
    17.         public void CreateQuest(){
    18.             // call out side function CreateQuest
    19.         }
    20.     }
    Code (csharp):
    1. using UnityEngine;
    2. using SimpleJSON;
    3. using BestHTTP;
    4. using System;
    5.  
    6. public class GameToolsQuests : MonoBehaviour {
    7.  
    8.     public void CreateQuest(){
    9.         HTTPRequest request = new HTTPRequest(new Uri(GameSettings.LPATH+"?page=quests&function=create_quest"), HTTPMethods.Post,create_quest_response);
    10.         request.AddField("session_id", GameSettings.session_id);
    11.         request.Send();
    12.     }
    13.  
    14.  
    15.     void create_quest_response(HTTPRequest request, HTTPResponse response) {
    16.  
    17.         JSONNode json_object = JSON.Parse(response.DataAsText);
    18.  
    19.  
    20.     }
    21. }
     
    Last edited: Jan 23, 2018
  5. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    910
    I just upgraded from version 5.6 to 2017.3p3 and all my inspector assignments were all set back to default.
    so everywhere I assigned a prefab or set something is all back to default.
    Text components are all fine. Seems it only effected components where Odin effected them.
    Is this a Odin issue? I've never had this happen before when upgrading versions.
    I've upgraded from version 4.6 to 4.7 and so forth all the way up to now with on issues except this time.

    Edit: It didn't effect any prefabs interesting enough. So just everything in the scene that Odin effected.
     
  6. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Thaaanks
    Hey, going to take a deeper look into your questions later. Just wanted to ask, did non-odin serialized members also get reset?
     
  7. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    910
    ya I think so. Thinking its not related to odin now. I'm reimporting my project again. I think I had a bad install of unity.
    This time I uninstalled it and deleted the Unity folder and then installed it. So just hold up on any on your end. I'll get back to ya.
     
  8. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    910
    Ya it happen on the 2nd time as well.
    Here is a list of variables it did it on.
    Only the ones in the scene. Interesting enough also only the Active GameObjects in the Scene too. Those inactive GameObjects are also assigned as prefabs too so that may be why as well.

    GameObject
    Enum
    And any Component Array or GameObject Array such as GameObject[] or Component[]


    Edit: Also it only effected the first scene that was loaded when first Loading the Project.
    I just checked another scene and everything is fine.
    There was a compile error I had to fix do to depreciated code. But after fixing them it never corrected the settings. I also restarted Unity after fixing the error before hitting save scene. Just to make sure.
     
    Last edited: Jan 24, 2018
  9. ben_unity409

    ben_unity409

    Joined:
    Nov 6, 2017
    Posts:
    2
    Hey! Odin is a great tool, it's really a pleasure to use it.

    Could you add a switch to the TableMatrixAttribute so it draws rows bottom-up -- row [0] on bottom and row [1] drawn above it, etc.?
     
  10. blitzvb

    blitzvb

    Joined:
    Mar 20, 2015
    Posts:
    284
    Hey,

    Is it possible to visualize simple array not list ?

    Thanks in advance
     
  11. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    67
    I've been getting on great with Odin since purchasing it a few weeks back - awesome asset! ...But I'm seeing a couple of problems in 1.0.6 as I'm trying to get my first OdinEditorWindow working.

    I'm setting up a tool window similar to the 'Some Texture Tool' example.
    • I have a field with a '[FolderPath(RequireValidPath = true)]' attribute. When I choose a folder I see errors in the console log. I notice the same errors when I choose a folder in the 'Some Texture Tool' example. Probably as a consequence of the error the 'invalid path' warning never goes away. This is the first of four errors:
    InvalidOperationException: Operation is not valid due to the current state of the object
    System.Collections.Generic.Stack`1[System.Boolean].Pop ()
    UnityEditor.EditorGUI.EndChangeCheck () (at /Users/builduser/buildslave/unity/build/Editor/Mono/EditorGUI.cs:323)
    Sirenix.OdinInspector.Editor.Drawers.FolderPathAttributeDrawer.DrawPropertyLayout (IPropertyValueEntry`1 entry, Sirenix.OdinInspector.FolderPathAttribute attribute, UnityEngine.GUIContent label) (at D:/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Attribute Drawers/FolderPathAttributeDrawer.cs:63)
    ...
    • The order that fields are shown in my window is wrong and doesn't seem to be changed by adding '[PropertyOrder()]' attributes. ...I have five editable properties and relative to their class definition order their display order is 3, 4, 1, 2, 5!
    • At the top of the window (and same for the demo ones too) I see a field called 'Persistent View Data Directory'. I notice that on the 'Basic Odin Editor' and 'Some Texture Tool' examples too. Seems odd?
    Thanks again for producing such an amazingly useful asset. Hope there're simple explanations for the above.
     
  12. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Did you get it solved? Not sure how I can help you I'm afraid. I would need a project that reproduced the problem when upgrading, in order to investigate it. And also some sort of hint that it could be Odin messing it up.
     
  13. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Thanks, and glad you like it :)

    Those were a couple of weird bugs, couldn't reproduce them on my end. What platform are you on? Could you share a script that reproduces both issues?

    This one is due to a bug in 2017.3, We've included a fix for it in the next patch. But you can also easily fix it yourself by copy and pasting this script into your project: http://www.sirenix.net/odininspecto...able-json-dictionary-in-my-odin-editor-window
     
  14. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Sadly not out of the box, but it's a popular request, and we want to add it. For now, though, you could achieve it by hiding the actual serialized two dim array, and and then expose a flipped version to the inspector and keep it updated in OnSerialize/OnDeserialize


    Code (CSharp):
    1. public class SomeComponent : SerializedMonoBehaviour
    2. {
    3.     [SerializeField, HideInInspector]
    4.     private bool[,] test = new bool[10, 5];
    5.  
    6. #if UNITY_EDITOR
    7.     [NonSerialized, ShowInInspector]
    8.     private bool[,] flipped;
    9.  
    10.     protected override void OnBeforeSerialize()
    11.     {
    12.         if (this.flipped != null)
    13.         {
    14.             Flip(this.flipped, ref test);
    15.         }
    16.     }
    17.  
    18.     protected override void OnAfterDeserialize()
    19.     {
    20.         Flip(this.test, ref this.flipped);
    21.     }
    22.  
    23.     private static void Flip(bool[,] a, ref bool[,] b)
    24.     {
    25.         var width = a.GetLength(0);
    26.         var height = a.GetLength(1);
    27.  
    28.         if (b == null || b.GetLength(1) != width || b.GetLength(0) != height)
    29.         {
    30.             b = new bool[height, width];
    31.         }
    32.  
    33.         for (int x = 0; x < width; x++)
    34.         {
    35.             for (int y = 0; y < height; y++)
    36.             {
    37.                 b[y, x] = a[x, y];
    38.             }
    39.         }
    40.     }
    41. #endif
    42. }
     
  15. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Hey :) What is an array not list? Could you post the code definition for it?
     
  16. blitzvb

    blitzvb

    Joined:
    Mar 20, 2015
    Posts:
    284
    LOL ;) i have to admit that my sentence was at best confusing ;)

    I meant an array like that :

    int[] numbers;

    Also I am wondering about struct if they can be shown in the inspector through Odin?
     
  17. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Hehe np, Yep and yep. Or it can show instances of structs to be accurate ;) You give Odin an instance of an object it then renders an editor for that object.

    Have you purchased Odin yet?
     
  18. blitzvb

    blitzvb

    Joined:
    Mar 20, 2015
    Posts:
    284
    Not yet but it’s on my cart for purchasing, next week ;)

    what really convince me is the editor window even though I guess it will not be super mature at first.
     
    Last edited: Jan 27, 2018
    bjarkeck likes this.
  19. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    67
    Sorry, I should have given more information before: my config is Unity 2017.3.0f3 under Mac OS 10.13.2. Odin version is 1.0.6. In case it matters, my Odin install is not in the default directory (it sits under 'Assets/ThirdParty/Editor')

    This is the editor code:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System;
    4. using System.IO;
    5. using Sirenix.OdinInspector.Editor;
    6. using Sirenix.OdinInspector;
    7. using Sirenix.Utilities.Editor;
    8. using Sirenix.Utilities;
    9.  
    10. public class NoiseTextureGenerator : OdinEditorWindow
    11. {
    12.     const int DEFAULT_SIZE = 256;
    13.  
    14.     [MenuItem("Tools/NoiseTextureGenerator")]
    15.     private static void OpenWindow()
    16.     {
    17.         var window = GetWindow<NoiseTextureGenerator>();
    18.         window.position = GUIHelper.GetEditorWindowRect().AlignCenter(600, 600);
    19.         window.titleContent = new GUIContent("Noise Texture Generator");
    20.     }
    21.  
    22.     private void OnEnable()
    23.     {
    24.         AllocTexture();
    25.     }
    26.  
    27.     [ShowInInspector]
    28.     [FolderPath(RequireValidPath = true, AbsolutePath = true)]
    29.     public string OutputPath
    30.     {
    31.         get { return EditorPrefs.GetString("NTG_filePath"); }
    32.         set { EditorPrefs.SetString("NTG_filePath", value); }
    33.     }
    34.  
    35.     [ShowInInspector]
    36.     public string OutputName
    37.     {
    38.         get { return EditorPrefs.GetString("NTG_fileName"); }
    39.         set { EditorPrefs.SetString("NTG_fileName", value); }
    40.     }
    41.  
    42.     private int[] textureSizeOptions = {
    43.         32, 64, 128, 256, 512, 1024
    44.     };
    45.  
    46.     [ValueDropdown("textureSizeOptions")]
    47.     [OnValueChanged("AllocTexture")]
    48.     public int size = DEFAULT_SIZE;
    49.  
    50.     [ReadOnly]
    51.     [InlineEditor(InlineEditorModes.LargePreview)]
    52.     public Texture2D texture;
    53.  
    54.     private void AllocTexture()
    55.     {
    56.         texture = new Texture2D(size, size, TextureFormat.RGBA32, false);
    57.     }
    58.  
    59.     [Button(ButtonSizes.Large), GUIColor(0, 1, 0)]
    60.     public void BuildTexture()
    61.     {
    62.         Debug.Log("GENERATE A NOISE TEXTURE...");
    63.     }
    64. }
    And this is how the editor looks:
    Screen Shot 2018-01-27 at 11.29.01 PM.png
     
  20. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Thanks a lot! I've tested in on Windows, and Linux without getting the issue, We'll borrow another MAC tomorrow and have a crack at it. In regards to the PropertyOrder not working for you, could you share a simple example for that as well?
     
  21. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    67
    For me this same script shows up both problems! (e.g. the screen grab above is what I see)

    I wonder if I should try a clean re-install of Odin? I can also check how things look on a PC. I'll report back with any feedback from both.
     
  22. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    67
    Before I got to trying a re-install I noticed that under 2017.3.0p4 I don't encounter the InvalidOperationException. I double checked and it definitely still happens every time under 2017.3.0f3 but totally fine with the patch build.

    On PC, under 2017.3.0p4 I don't see the InvalidOperationException either. I also tried under 2017.2.0f3 (version I had last been using on my PC) and that was fine too.

    On both Mac and PC the properties are displayed in the wrong order, i.e. the size field and texture inspector are above the two path fields.
     
  23. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Ah thought you were using the PropertyOrder attribute which is required to get proper ordering between various member types.

    C# Doesn't provide any way to get all members in the order in which they were declared in the file. However when we ask for all fields or all properties, they do come in the right order.

    So the way we do order it in Odin is:
    1. All fields,
    2. All properties,
    3. All methods

    if you then want to have a method or a property to be shown before all fields, or just at a specific location you can then give the property a [PropertyOrder(x)] attribute and specify a custom order for it (default is 0)

    Code (CSharp):
    1.  
    2. public int a;
    3.  
    4. [PropertyOrder(2)]
    5. public int c;
    6.  
    7. [ShowInInspector, PropertyOrder(1)]
    8. public int b {get;set;}
    9.  
    10. [Button, PropertyOrder(-10)]
    11. public int ButtonAtTop() {}
     
  24. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    67
    Right, that makes sense. I thought I had tried the PropertyOrder(-10) approach but I just tried that again and it works great. So... My apologies for any confusion, and many thanks for your help!
     
    bjarkeck likes this.
  25. arachnidLeo

    arachnidLeo

    Joined:
    Nov 22, 2012
    Posts:
    4
    Hey guys! Love the tool, we've been using it since beta.

    I'm having an issue that's seemingly new to 1.0.6. When using an [AssetList] with a custom filter method, it gets confused if the input object is a child class of the class you're validating with. For example see below: (this used to work)
    upload_2018-1-31_16-9-56.png

    In the inspector, when I ref any object that's a child class of Objective, I get this error:
    upload_2018-1-31_16-11-41.png
    Even though DefaultObjective is a type of Objective.

    Am I doing something wrong or is this a bug?
     
  26. PuzzledBoy

    PuzzledBoy

    Joined:
    Sep 9, 2014
    Posts:
    7
    Unity crash in apply prefab which contains both component "SeriMonoBehaviour" and "DOTweenAnimation".

    Hi,My team's project works with both odin and DOTween Pro,but I was bothered by a Odin's bug found 3 days ago,still can't work with it now.
    I need some help... QAQ

    I create an Script named "TestOdin" :

    Code (CSharp):
    1. public class TestOdin : SerializedMonoBehaviour
    2. {
    3. public BaseData data;
    4. }
    5. [Serializable]
    6. public abstract class BaseData
    7. {
    8. public int data;
    9. }
    10. [Serializable]
    11. public class Data1 : BaseData
    12. {
    13. }
    1.Create a gameobject named "TestNoDOTween";
    2.Add Script "TestOdin" Script to it;
    3.Drag gameobject to project window to create a prefab;
    4.change the field "data" on "TestNoDOTween" ,apply prefab, work great;

    5.Create a gameobject named "TestWithDOTween";
    6.Add Script "DOTweenAnimation" and "TestOdin" to it;
    7.Drag gameobject to project window create a prefab;
    8.change the field "data" on "TestWithDOTween",apply prefab, Unity Crash.

    9.if you still don't get the error,try save project,close and reopen unity,then try step 4 and step 8 again,and you will get a crash at step 8.

    See download for crash Editor.log.
    Try at Unity5.6,Unity5.3,and Unity 2017.3

    Thank you...
     

    Attached Files:

  27. mSkull

    mSkull

    Joined:
    Apr 19, 2016
    Posts:
    9
    This is definitely a bug. We'll be sure to have a fix for this soon.
     
  28. PuzzledBoy

    PuzzledBoy

    Joined:
    Sep 9, 2014
    Posts:
    7
    After another day testing, I found that it isn't a conflict between Odin and DOTweenPro.
    The crash bug happens because the DOTweenAnimation component contains an UnityEvent field,I have try create a custom MonoBehavioud with only an public UnityEvent field ,use it to replace the DOTweenAnimation component and get the same crash error.

    Here is my steps:
    1. Create a script named "TestClassUnityEvent":
    Code (CSharp):
    1. public class TestClassUnityEvent : MonoBehaviour
    2. {
    3.         public UnityEvent testUnityEvent;
    4. }
    2. Create a script named "TestOdin":
    Code (CSharp):
    1. public class TestOdin : SerializedMonoBehaviour
    2. {
    3.     public BaseData data;
    4. }
    5.  
    6. [Serializable]
    7. public abstract class BaseData
    8. {
    9.     public int data;
    10. }
    11.  
    12. [Serializable]
    13. public class Data1 : BaseData
    14. {
    15.    
    16. }
    3. Create an empty gameobject, add script "TestClassUnityEvent" and "TestOdin" to it.
    4. Drag the gameobject to create a prefab.
    5. Change value of field 'Data',then apply prefab, everything work great.
    6. Save scene,close and reopen unity, change field 'Data' 's value, apply prefab, Unity Crash.
    7. If you don't get the crash at step 6, try change the field value by scroll you mouse at field name 'Data' instead of type your value in the right input box.
    upload_2018-2-3_22-19-25.png

    The strange things is , sometime I get crash just type value in the input box, sometime it work fine, and scroll the field name get crash, Can't figure out what happens here.

    Can anyone get the same error as mine?
    Thanks~
     

    Attached Files:

  29. PuzzledBoy

    PuzzledBoy

    Joined:
    Sep 9, 2014
    Posts:
    7
    I replace the script "TestClassUnityEvent" by UGUI "Button" which absolutely exists a UnityEvent field 'OnClick'. Get the same crash ,It must be the UnityEvent field conflict with Odin.
     
  30. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Btw, we also managed to reproduce the FolderPath and FilePath issue you had on a MAC, so those will be fixed in the next patch. Thanks again.
     
    trepan likes this.
  31. vzlomvl

    vzlomvl

    Joined:
    Jun 25, 2016
    Posts:
    13
    Hello. Tell me please whether there is an similar PreviouslySerializedAs attribute for the class name in Oidn Serialization system? I looking simple way to rename class name or class namespace without lost serialized data. Thanks.
     
  32. dearamy

    dearamy

    Joined:
    Mar 17, 2015
    Posts:
    68
    Is there any way to add the "MinValue" and "MaxValue" attribute to the Vector2Int and the Vector3Int?
     
  33. Dimlos

    Dimlos

    Joined:
    Aug 13, 2014
    Posts:
    30
    Hello I have a very specific problem.

    I have an array of icons on each of my abilities.
    Most of them only use one but some can have more.

    The only problem is that since it's an array of Images, if I click the little pen, it displays the entire texture sheet.
    So I tried to use the [PreviewField] but it does not work with an array.

    What would be nice is if I could add in the attribute a string refering to a function where I tell him which object to be set to. Maybe something like this? Or maybe there is already something I can use that I missed?

    Code (CSharp):
    1. Image[] imageList;
    2.  
    3. [PreviewField("SetImage")]] Image previewImage;
    4.  
    5. #if UNITY_EDITOR
    6. void SetImage()
    7. {
    8.    if(imageList.Count > 0)
    9.        if(imageList[0] != null)
    10.            previewImage = imageList[0];
    11. }
    12. #end if
    EDIT:

    I managed to do something similar by using OnValidate(). it works fine:

    Code (CSharp):
    1.  
    2. Image[] imageList;
    3.  
    4. [PreviewField] Image previewImage;
    5.  
    6. private void OnValidate()
    7. {
    8.     if (icone != null)
    9.         if(icone.Length > 0)
    10.             if (icone[0] != null)
    11.                 previewIcone = icone[0];
    12. }
    13.  
     

    Attached Files:

    Last edited: Feb 13, 2018
    bjarkeck likes this.
  34. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    It's not yet, unfortunately, but you could easily add that yourself with a simple drawer ;)

    Code (CSharp):
    1. [OdinDrawer]
    2. [DrawerPriority(0.3)]
    3. public sealed class MinValueAttributeVector2IntDrawer : OdinAttributeDrawer<MinValueAttribute, Vector2Int>
    4. {
    5.     protected override void DrawPropertyLayout(IPropertyValueEntry<Vector2Int> entry, MinValueAttribute attribute, GUIContent label)
    6.     {
    7.         this.CallNextDrawer(entry, label);
    8.         Vector2Int v = entry.SmartValue;
    9.         if (attribute.MinValue > v.x ||
    10.             attribute.MinValue > v.y)
    11.         {
    12.             v.x = attribute.MinValue > v.x ? (int)attribute.MinValue : v.x;
    13.             v.y = attribute.MinValue > v.y ? (int)attribute.MinValue : v.y;
    14.             entry.SmartValue = v;
    15.         }
    16.     }
    17. }
    We'll be polishing Vector2Int and Vector3Int in the near future as well, and when we get around to it we'll make sure that works as well.
     
  35. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    It's something we've always wanted, so I went and added a new attribute that lets step in to the process of the Sirenix.Serialization.DefaultSerializationBinder and lets you bind type names to types.

    Code (CSharp):
    1. [assembly: Sirenix.Serialization.BindTypeNameToType("NameSpace.OldTypeName", typeof(NewTypeName))]
    Do note that it's only actually needed if you're serializing abstract classes or interfaces etc. Odin is by default be resilient, and will always try and recover as much data as possible, and a lot of the time the new Type name is given by the member declaration type. But if it doesn't know which new Type to do it in, this is where the attribute becomes useful.
     
  36. Alex_May

    Alex_May

    Joined:
    Dec 29, 2013
    Posts:
    117
    I have an OdinEditorWindow that I want to use to display Odin inspectors for various objects derived from SerializedScriptableObject, containing lists. How would I do this? I have got as far as loading in the assets, creating a serializedobject for each SerializedScriptableObject, then using propertyfields in editorguilayout to draw the properties, but this doesn't seem to pick up fields serialized by odin that are unrecognised by unity. Also tried creating an editor with Editor.CreateEditor, then using DrawDefaultInspector but this obviously just draws the unity inspector and not Odin's.

    What do I do? A bit lost. Thanks!

    edit: Just read Tor's post above (https://forum.unity.com/threads/rel...e-ultimate-workflow-tool.476949/#post-3143015) and gonna do some more experimentation. Thanks - ignore for now
     
    Last edited: Feb 16, 2018
  37. Alex_May

    Alex_May

    Joined:
    Dec 29, 2013
    Posts:
    117
    Yeah, I'm getting
    Code (CSharp):
    1. ArgumentException: GUILayout: Mismatched LayoutGroup.Repaint
    When calling OnInspectorGUI from OnGUI - something I'm doing wrong?

    edit:

    Fixed it! Caching my editors fixed the issue - previously I was creating them in OnGUI.
    Working code:
    Code (CSharp):
    1. using System.IO;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEditor;
    6. using Sirenix.OdinInspector.Editor;
    7. using Sirenix.OdinInspector;
    8. class FormEditor
    9. {
    10.     public Form form;
    11.     public Editor editor;
    12. }
    13.  
    14. public class BasicFormaEditor : OdinEditorWindow {
    15.    
    16.     Dictionary<string, FormEditor> fdb;
    17.  
    18.     [MenuItem("Forma/Simple database editor")]
    19.     public static void OpenWindow()
    20.     {
    21.         var window = GetWindow<BasicFormaEditor>();
    22.         window.titleContent = new GUIContent("Forma database editor");
    23.     }
    24.  
    25.     protected override void OnEnable()
    26.     {
    27.         Debug.Log("Opening forma basic editor...");
    28.         fdb = new Dictionary<string, FormEditor>();
    29.  
    30.         DirectoryInfo dirInfo = new DirectoryInfo("Assets/Forma");
    31.         FileInfo[] fileInf = dirInfo.GetFiles("*.asset");
    32.         foreach (FileInfo fileInfo in fileInf)
    33.         {
    34.             string fullPath = fileInfo.FullName.Replace(@"\", "/");
    35.             string assetPath = "Assets" + fullPath.Replace(Application.dataPath, "");
    36.             Form o = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Form)) as Form;
    37.             Debug.Log("Loaded Form " + o.name);
    38.             FormEditor fe = new FormEditor();
    39.             fe.form = o;
    40.             fe.editor = Editor.CreateEditor(o);
    41.             fdb[o.name] = fe;
    42.         }
    43.     }
    44.  
    45.     protected override void OnGUI()
    46.     {
    47.         foreach (FormEditor formEditor in fdb.Values)
    48.         {
    49.             formEditor.editor.OnInspectorGUI();
    50.         }
    51.     }
    52.  
    53. }
     
    Last edited: Feb 16, 2018
    bjarkeck likes this.
  38. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Here is another way you can do it :)

    Code (CSharp):
    1. public class BasicFormaEditor : OdinMenuEditorWindow
    2. {
    3.     [MenuItem("Forma/Simple database editor")]
    4.     public static void OpenWindow()
    5.     {
    6.         var window = GetWindow<BasicFormaEditor>();
    7.         window.titleContent = new GUIContent("Forma database editor");
    8.     }
    9.  
    10.     protected override OdinMenuTree BuildMenuTree()
    11.     {
    12.         var menuTree = new OdinMenuTree(true);
    13.         menuTree.AddAllAssetsAtPath("", "Assets/Forma", typeof(Form), true, true);
    14.         menuTree.Selection.AddRange(menuTree.EnumerateTree()); // Select all if you want.
    15.         return menuTree;
    16.     }
    17. }
    Or

    Code (CSharp):
    1. public class BasicFormaEditor : OdinEditorWindow
    2. {
    3.     [MenuItem("Forma/Simple database editor")]
    4.     public static void OpenWindow()
    5.     {
    6.         var window = GetWindow<BasicFormaEditor>();
    7.         window.titleContent = new GUIContent("Forma database editor");
    8.     }
    9.  
    10.     List<UnityEngine.Object> targets;
    11.  
    12.     protected override void OnEnable()
    13.     {
    14.         base.OnEnable();
    15.  
    16.         this.targets = AssetDatabase.FindAssets("t:Form")
    17.             .Select(x => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(x), typeof(Form)))
    18.             .ToList();
    19.     }
    20.  
    21.     protected override IEnumerable<object> GetTargets()
    22.     {
    23.         return this.targets;
    24.     }
    25. }
    Check out the Odin Editor Windows demo from the getting started guide in Unity :)
    And the online documentation is here: http://sirenix.net/odininspector/documentation/sirenix/odininspector/editor/odinmenueditorwindow
     
    Alex_May likes this.
  39. Alex_May

    Alex_May

    Joined:
    Dec 29, 2013
    Posts:
    117
    Whoah, mind blown. Thanks!
     
    bjarkeck likes this.
  40. Laicasaane

    Laicasaane

    Joined:
    Apr 15, 2015
    Posts:
    24
    It would be nice if TabGroup can be nested inside TitleGroup. And there should be a way to draw List & Array as tabs. At the moment I can only draw my List inside a tab, which is not what I expected.

    For example, I have X, Y, Z, W of List<Vector3>, some fields and buttons, and I want to show them like this:
    TabGroup inside TitleGroup and List as Tab.png
     
    Last edited: Feb 24, 2018
  41. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    I see. All groups can be placed into each other like so:
    Code (CSharp):
    1. [TitleGroup("TitleGroup")]
    2. member
    3.  
    4. [TabGroup("TitleGroup/Some Tab Group", "X")]
    5. member
    TabGroups can be a little confusing at first because they actually make two groups. One group for which tab group it is, and another group for which tab it is.

    So when you say [TabGroup("My Tab")] It's actually just a shortcut to [TabGroup("_DefaultTabGroup", "My Tab")] if that makes sense? So if you wanted to place a group inside a tab you would then write [FoldoutGroup("_DefaultTabGroup/My Tab/MyFoldout")]
     
    Laicasaane likes this.
  42. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    133
    I have a similar setup in a custom editor I'm working on, however the conditional blocks have different quantities of properties inside them. I should also point out that I'm trying to work with Odin's PropertyTree, InspectorProperty and InspectorProperty.Draw() members.

    What is the recommended way of dealing with conditionals that are based on values that change during OnGUI?

    For example, if a property is changed and that property's value is used in a later switch that draws 0 to 6 other properties, exceptions will occur.

    Code (CSharp):
    1. DrawProperty0();
    2. var value = GetProperty0Value();
    3.  
    4. switch (value)
    5. {
    6.    case 0:
    7.       // Nothing
    8.       break;
    9.  
    10.    case 1:
    11.       DrawProperty1();
    12.       DrawProperty2();
    13.       DrawProperty3();
    14.       DrawProperty4();
    15.       DrawProperty5();
    16.       DrawProperty6();
    17.       break;
    18.  
    19.    case 2:
    20.       DrawProperty1();
    21.       DrawProperty2();
    22.       DrawProperty3();
    23.       break;
    24. }
    25.  
    26. DrawAnotherProperty();
    The pseudo code above would generate exceptions because the number of controls are changing between the layout and repaint GUI passes.

    Is there some way to delay or defer the actual value change until after repaint? I've noticed there's "DelayActionUntilRepaint(Action)", however I'm not sure if that's intended for this type of situation.

    If it matters, the above conditional value used by the switch comes from an Enum property.
     
    Last edited: Mar 2, 2018
  43. Barabicus

    Barabicus

    Joined:
    Jun 5, 2013
    Posts:
    144
    Hey,
    How would I go about creating a drag and drop area that I could handle what to do with all the dragged objects myself through custom code? Imagine just a black box that you can drag a bunch of items to.
     
  44. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Take a look at the DragAndDropUtilities class, it has a lot of helper methods.

    So it would look something like:

    Code (CSharp):
    1. var id = DragAndDropUtilities.GetDragAndDropId(..);
    2. DragAndDropUtilities.DrawDropZone(...);
    3. var doppedObjects = DragAndDropUtilities.DropZone<Type>(...);
     
  45. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    You would have to hold a copy of the value and swap it out with the modified one, in repaint. The method DelayActionUntilRepaint could help with that, but it's mostly just needed in drawers. Curious though, is there a reason you are drawing individual properties manually? Usually just drawing the entire property tree and use [HideIf/ShowIf] attributes get the job done. Also, have you seen the Odin Editor Window examples from our getting started guide in Unity?

    If you could share more of your code, maybe I would be able to give some pointers :)
     
  46. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    133
    Thanks for the information. I wasn't sure if the InspectorProperty featured anything (a flag or mode) that would hold the value change and apply it during repaint, so I thought I'd ask.

    Since adding Odin to our project, I usually just use attributes to draw things these days, because they're so much faster. I have quite a bit of experience writing custom Inspectors that subclass Editor, but this will be my first experience using OdinEditor and PropertyTree.

    In this situation, I'm dealing with a UnityEngine.UI.Button subclass, and I'm trying to recreate the Unity's default Button inspector for members of the base class while also drawing subclass members using Odin attribute markups when possible.

    My understanding is that there is no way to draw Unity's default custom Button editor from inside the OdinEditor. While I'm able to access and draw all serialized base class members, none of the custom behavior present in the Button editor is retained, such as selectively hiding certain fields until other fields contain specific values.

    The base class members also draw in an unusual order when just drawing the entire property tree. New subclass members draw last unless they have the PropertyOrder attribute on them, but that can't be used on the base class members to re-order them. It's probably possible to add an attribute to the Button class members at runtime using reflection, but I've never tried that and thought simply rebuilding the default editor would be easier.

    If there is an easier way of getting the default Button editor to draw along with new subclass members with Odin attribute markup, please let me know. Thanks!
     
  47. Barabicus

    Barabicus

    Joined:
    Jun 5, 2013
    Posts:
    144
    Thank you exactly what I was looking for! :)
    Also while I'm here is it possible if you could add support for OnSceneGUI much like you can use OnInspectorGUI? To my knowledge that is the only way you can draw handles I think?
     
  48. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Aaah, I Hope I understood that correctly but sounds it sounds like you can draw it by creating an Editor for it: https://docs.unity3d.com/ScriptReference/Editor.CreateEditor.html

    This is also the same technique we use to get the InlineEditor attribute to work, regardless of whether Odin or Unity is drawing it actually. That way if there exists custom editor, we'll use those.
     
  49. bjarkeck

    bjarkeck

    Joined:
    Oct 26, 2014
    Posts:
    214
    Great :) In regards to an OnSceneGUI attribute, would you prefer that it would be called constantly or only when the value containing the attribute is visible?
     
  50. vzlomvl

    vzlomvl

    Joined:
    Jun 25, 2016
    Posts:
    13
    Thanks. As I understand attribute BindTypeNameToType will be available in next version of Odin?
    And some another question. I have array of elements(not struct). To serialize this data I use Odin Serializetion system(SerializationData and UnitySerializationUtility). If I add element in beginning of array, ID of all next elements change. If size of array is big its a lot of changes in file. Its complicates work with git diff and validate commits. I not using internal references in this data. So my question is: Can I turn off reference Id serialization in Node data format(or at all)?