Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Open Source] VFW (135): Drawers. Save System and full exposure

Discussion in 'Assets and Asset Store' started by vexe, Sep 2, 2014.

  1. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @osxhacker thanks for dropping by. And yes you're correct. It's a refactoring mistake. Fixed in next version. Hope you find the FW useful. And please let me know of any bugs you find. If you have any questions/suggestions don't hesitate to ask.
     
  2. coAdjoint

    coAdjoint

    Joined:
    Jul 18, 2012
    Posts:
    162
    Absolutely fantastic project, I will be giving you full credit when I use this for a future (free) release!
     
  3. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @coAdjoint thanks for dropping by. Feel free to use VFW however you like, in both free and commercial works :) - Also if you can, give credits to @sient (jacobdufault) the author of FullSerializer as his serializer is the back-bone of my serialization system.

    Just released 1.2 with some important fixes, new attributes and some breaking (but important) changes. I decided to take out the extra serializers, I know this makes the framework less flexible, but FullSerializer does everything anyone would want from a serializer and there's no practical reason for the most part for anyone to use another serializer. This makes the framework simpler, more robust and less error prone since there's only one serializer to worry about.

    I will keep the previous 1.1.4 build around for a while in case anyone is still interested in the multi-serializers feature. It's really easy to integrate them anyway.

    As for the saving system, I couldn't find time to fully test it and release it along side 1.2, I'm currently just wanting a sample project to test it on. It might be commercial though I'm not sure yet.
     
  4. coAdjoint

    coAdjoint

    Joined:
    Jul 18, 2012
    Posts:
    162
    Will do. For the purposes of this project, I've stripped out all the properties drawers and GUI stuff as I'm only interested in abstract class serialisation and I don't want to force my users to use a particular GUI system like Rabbit (nothing wrong with it of course!)

    The software will be release for free as well but thanks for your permission anyway. I occasionally do tutorial videos and would like to demo how I'm using inheritance in my current project, I'll be sure to credit you and @sient and point people towards your YouTube channel.

    Keep up the good work!
     
  5. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    As you wish. One thing I'd like to request from you though, please pronounce my name correctly if you ever mention it in your videos lol. People usually get it wrong pronouncing it "Vexy", "Vixi", "Vexai" etc. The 'e' is silent at the end, so it's just "vex", as in "Rex". And thanks :D
     
    Last edited: Dec 5, 2014
  6. CptTeacup

    CptTeacup

    Joined:
    Jul 19, 2014
    Posts:
    11
    Just started using this plugin and I'm loving it so far. This functionality really should have been part of Unity in the first place.

    I have a couple questions:
    Is it possible to serialize static members?
    Can members shown in the inspector be listed in the order that they were declared?
     
  7. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    Very good project indeed. Why don't you put it in the Unity Asset Store so we can manage updates easier?

    By the way 1.2 does not work properly :

    Assets/3rd Party/Vexe/Vexe/Runtime/Types/Core/BetterBehaviour.cs(38,25): error CS0118: `Vexe.Runtime.Types.BetterBehaviour.SerializationData' is a `property' but a `type' was expected

    Assets/3rd Party/Vexe/Vexe/Runtime/Types/Core/BetterBehaviour.cs(13,10): error CS0246: The type or namespace name `DefineCategory' could not be found. Are you missing a using directive or an assembly reference?

    Assets/3rd Party/Vexe/Vexe/Runtime/Types/Core/BetterBehaviour.cs(13,10): error CS0246: The type or namespace name `DefineCategoryAttribute' could not be found. Are you missing a using directive or an assembly reference?

    Assets/3rd Party/Vexe/Vexe/Runtime/Examples/Scripts/Attributes/DisplayOrderExample.cs(10,10): error CS0246: The type or namespace name `MinimalView' could not be found. Are you missing a using directive or an assembly reference?

    Assets/3rd Party/Vexe/Vexe/Runtime/Examples/Scripts/Delegates/DelegatesExample.cs(14,44): error CS0246: The type or namespace name `uAction' could not be found. Are you missing a using directive or an assembly reference?

    Assets/3rd Party/Vexe/Vexe/Runtime/Examples/Scripts/Delegates/DelegatesExample.cs(19,42): error CS0246: The type or namespace name `uFunc`1' could not be found. Are you missing a using directive or an assembly reference?
     
    Last edited: Dec 13, 2014
  8. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @sGlorz Thanks for dropping by. I don't like the asset store, I don't see how it would make updates easier, if anything, it would make them harder. Many users have used 1.2 just fine. All of these 'missing' types are there, you shouldn't get any of them. Could you try importing to an empty project?
     
  9. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @CptTeacup

    1- Is it possible to serialize static members?
    --- Yes. I can both serialize and expose them. But I don't have that functionality in yet. I don't see great value of doing that. If you could convince me otherwise I will be happy to consider it.

    2- Can members shown in the inspector be listed in the order that they were declared?
    --- Yes, but it's quite tricky I decided it's not worth the effort. Thing is, if you only have fields it's not a problem, GetFields already seems to get the fields in the order they're declared in. But when properties get involved, GetMembers doesn't get the ordered result one would expect. I currently have members ordered by FieldsThenPropertiesThenMethods, then by data type name (so floats come before ints) then by the member name. You could explicitly specify the order by annotating with [DisplayOrder(someValue)]
     
    Last edited: Dec 13, 2014
  10. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Just put up 1.2.4 with tons of editor fixes. Everyone make sure you update. I've removed the 1.1.4 file cause it's quite out-dated now. If anyone wants the previous extra serializers let me know I still have the old versions. In 1.2.4 I've simplified the drawing API to work only with fields/properties and handle methods as a special case, which drastically simplifies and make things more robust.

    No SaveSystem yet... I'm busy doing other stuff. The source for the system is quite stable, I just need put it into test on some simple project but I don't have the time. If anyone is interested in giving it a try, let me know and I'll send you a VFW version with the SaveSystem so you could mess with it and see what it's all about.
     
  11. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    Everything works perfectly in an empty project.
    Moreover, I've tested version 1.2.4 and after some renaming (dmValue, usings, etc...) all went well.

    Perfect!

    P.S.: Could you add something to test the version and be sure the latest is used?
     
  12. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @sGlorz, if it's at all possible, next time remove any older version and import the new (I don't quite trust the unity importer) so you don't need to rename etc unless you were using something in your own codes from the framework.
     
  13. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    I always remove older version before importing new one, for the same reason as you :)
     
  14. CptTeacup

    CptTeacup

    Joined:
    Jul 19, 2014
    Posts:
    11
    It would just be a matter of convenience for accessing members of singletons that are set from the inspector rather than at runtime, not hugely important.

    Anyway, thanks for your generosity in providing this plugin for free, it has already saved me a lot of pain.
     
  15. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @CptTeacup I thought singletons have instance members, don't they?
    Code (csharp):
    1.  
    2. public class SingleClass : BetterBehaviour
    3. {
    4.     public static Instance { get { ... } }
    5.     public int Value { get; set; }
    6.     public string Band { get; set; }
    7. }
    8.  
    That's totally inspectable, you'd still be able to see Value and Band
     
  16. CptTeacup

    CptTeacup

    Joined:
    Jul 19, 2014
    Posts:
    11
    Ah, that makes things easier. Thanks!
     
  17. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @CptTeacup If singletons are your cup of tea (see what I just did there?), you might be interested in this singleton idea.The idea is to have a custom behaviour (game-dependent) that will hold references to anything you want to be single. You do this in the editor. The references you expose are wrapped in properties such then when you set a value it gets registered in a static singleton system. The references are inlined for pure convenience. Here's an example from my inventory

    Code (csharp):
    1.  
    2. [BasicView, ExecuteInEditMode]
    3. public class IOUSingles : BetterBehaviour
    4. {
    5.    [Hide, Serialize] ItemSystem _itemSystem;
    6.    [Hide, Serialize] CombineSystem _combineSystem;
    7.    [Hide, Serialize] UseSystem _useSystem;
    8.  
    9.   [Show, Inline(GuiBox = false)]
    10.    public ItemSystem ItemSystem
    11.    {
    12.      get { return _itemSystem; }
    13.      set
    14.      {
    15.        _itemSystem = value;
    16.        Singleton.Set(value);
    17.      }
    18.    }
    19.  
    20.    [Show, Inline(GuiBox = false)]
    21.    public CombineSystem CombineSystem
    22.    {
    23.      get { return _combineSystem; }
    24.      set
    25.      {
    26.        _combineSystem = value;
    27.        Singleton.Set(value);
    28.      }
    29.    }
    30.  
    31.    [Show, Inline(GuiBox = false)]
    32.    public UseSystem UseSystem
    33.    {
    34.      get { return _useSystem; }
    35.      set
    36.      {
    37.        _useSystem = value;
    38.        Singleton.Set(value);
    39.      }
    40.    }
    41.  
    42.    void OnEnable()
    43.    {
    44.      Singleton.Set(ItemSystem);
    45.      Singleton.Set(CombineSystem);
    46.      Singleton.Set(UseSystem);
    47.    }
    48. }
    49.  
    50. public static class Singleton
    51. {
    52.    public static T Get<T>() where T : class
    53.    {
    54.      return InternalSingleton<T>.Get();
    55.    }
    56.  
    57.    public static void Set<T>(T single) where T : class
    58.    {
    59.      InternalSingleton<T>.Set(single);
    60.    }
    61.  
    62.    private static class InternalSingleton<T> where T : class
    63.    {
    64.      private static T singleton;
    65.  
    66.      public static T Get()
    67.      {
    68.        return singleton;
    69.      }
    70.  
    71.      public static void Set(T single)
    72.      {
    73.        Debug.Log("setting " + single);
    74.        singleton = single;
    75.      }
    76.    }
    77. }
    78.  
    Once you have your behaviour and references all setup, then you could: var whatever = Singleton.Get<Whatever>(); - Which I think is kind of cleaner than the Instance thing. If you make that behaviour a prefab, then all you need is to drop it in whatever scenes you want your stuff to be available.

    Note that if you only want your singles to be available at runtime, you don't need to set them in your properties, just set them in OnEnable. I have it setup that way cause I access these from both editor and runtime codes.

     
    Last edited: Dec 15, 2014
  18. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Guys I forgot to mention that 'readonly' fields are serialized too! In both BetterBehaviours and regular system object classes (when serialized by FullSerializer of course). And the coolest thing is that you could still be able to modify them in the inspector :)

    I find that quite useful actually. A lot of times I have a variable that I only set from the inspector but never modify from code, and there are objects interested in reading it. So usually I create a readonly property for that (a public property with a private setter) but the problem is that sometimes you want your variables to be initialized, you can't initialize properties in a straight forward manner, you'd either have to do it in some initialization method. So in that case I create private serialized variables with a public property around it for reading. But with readonly fields, we get the best of both words. So we can do:

    Code (csharp):
    1.  
    2. public readonly uAction SomeAction = new uAction();
    3.  
    instead of:
    Code (csharp):
    1.  
    2. [Serialize] private uAction someAction = new uAction();
    3. public uAction SomeAction { get { return someAction; } }
    4.  
     
    Last edited: Dec 15, 2014
  19. CptTeacup

    CptTeacup

    Joined:
    Jul 19, 2014
    Posts:
    11
    I see it and am quite vexed.

    Doesn't that defeat the purpose? It's used just like var whatever = FindObjectOfType<Whatever>(); which is what you would do without statics.
     
  20. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Not quite...
    1. With FindObjectOfType you can only find UnityObjects, but with this single service you could set any system object.
    2. This single system is more a service provider than a singleton in that you could specify exactly which services to register, with FindObjectOfType you never know what instance you'll get back if you had more than one. For ex, I found that useful in my situation where I had a database of items and what triggers they're used on. When you use a certain item on a trigger, that entry in the data base is no longer needed, but if I were to remove it I would be modifying the actual database prefab. So instead of that, I instantiate a scene database and register that instead. So if an entry is deleted, it wouldn't affect the actual database that's in the prefab (or asset file).
    3. FindObjectOfType is terribly slower. While Single.Get just gets you whatever instance associated with the generic type you're specifying. O(1) It doesn't do any searching
    4. Since the behaviour (the script that contains your references, in my ex IOUSingles) is in the scene, you're guaranteed to get a valid reference unlike for ex Resources.FindObjectsOfTypeAll which only gives you back objects loaded into memory, or FindObjectOfType which give you scene objects. You don't have to worry if the reference is in scene or an asset
    5. It's a tiny more elegant that your regular singleton.instance, there's nothing happening behind the scenes, no lazy instantiation etc. You don't have to inherit from some singleton script for your stuff to be single, they don't even know that this service exist. You just drop whatever you want to be single, they don't know about it.
    6. It kind of makes it clearer (more than .instance) what the dependencies are for your game, you just look at that scene behaviour and see what systems/managers it references
    7. Since all your core systems are referenced from one script and inlined, it makes inspecting and editing them easier, you don't have to drill down your project hierarchy searching for your manager assets/prefabs
     
    Last edited: Dec 16, 2014
  21. snw

    snw

    Joined:
    Mar 13, 2014
    Posts:
    42
    Hi vexe,

    I just encountered the limitations of Unity exposing properties, interfaces etc. and your extension comes to the rescue - thank you so much for your effort!

    I only scratched the surface of VFW, so I don't know if this feature already exists:
    Is there a way to reorder items of an array or list in the Editor? If not, do you plan to implement that kind of functionality or would i have to implement it myself?

    cheers
     
  22. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @snw thanks for dropping by.

    And yes, sure:
    Code (csharp):
    1.  
    2. [Seq(SeqOpt.Advanced)]
    3. public List<string> Names { get; set; }
    4.  
    This gives you a check box for some sequence operations, shuffle, reorder, shift whole list up/down, filter nulls, set new size, per item removal, and if it's a list of Components or gameObjects you get a button to inspect each element quickly in a new inspector window. There's a SequencesExample.cs script, check that out too.
     
    Last edited: Dec 16, 2014
  23. snw

    snw

    Joined:
    Mar 13, 2014
    Posts:
    42
    Got it. Awesome!
     
  24. coAdjoint

    coAdjoint

    Joined:
    Jul 18, 2012
    Posts:
    162
    Hi vexe, wondering if you can help with a little problem i'm having. I'm trying to serialize some custom classes which contain lists. If I don't press play before exiting Unity (regardless of saving the scene) sometimes an instance of the class isn't serialised. Any ideas about how to ensure serialisation? Happy to send you a project if necessary.
     
  25. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @coAdjoint I'm afraid I need more information to be able to help. If you can send a project/sample code it'd be great.
     
  26. CptTeacup

    CptTeacup

    Joined:
    Jul 19, 2014
    Posts:
    11
    Ah, makes a lot more sense, thanks! I'll probably start using that now.
     
  27. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    Hello

    Sometimes my ObjectDrawer is not draw when application is not running. But after,selecting/unselecting the object a couple of time, my drawer is drawn. When the application is running, the drawer is always drawn.

    Unity bug ?

    Here is the failing code:
    Code (CSharp):
    1.  
    2. [Serializable]
    3. public class HitRule
    4. {
    5.   public MovingStatus Moving;
    6.   public bool ExecRule;
    7.   public int TriggerRuleNumber;
    8.   public AppliedDamage AppliedDamage;
    9.   public float Damage;
    10.   public float DamageForce;
    11. }
    12.  
    13. [Category("Hit"), Seq(SeqOpt.Advanced | SeqOpt.LineNumbers | SeqOpt.PerItemRemove), PerItem]
    14. public HitRule[] HitRules;
    15.  
    16. public class HitRuleDrawer : ObjectDrawer<MovingElement.HitRule>
    17. {
    18.   public override void OnGUI()
    19.   {
    20.     // No value, nothing to do
    21.     if (memberValue == null || gameObject == null) return;
    22.    
    23.     // Start horizontal section
    24.     using (gui.Horizontal())
    25.     {
    26.       gui.DrawLabel("If hit while moving");
    27.       gui.DrawSpaceChar(1);
    28.       memberValue.Moving = (MovingElement.MovingStatus)gui.EnumPopup(string.Empty, memberValue.Moving, GuiHelper.GetEnumMaxWidth(typeof(MovingElement.MovingStatus)));       }
    29.   }
    30. }
    31.  
     
  28. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @sGlorz that's fixed in next version which I will be releasing soon. The problem is, when I initialize a drawer I only do it once, but when you select/deselect a gameObject a new editor instance is created with a different gui instance so your drawer is still using the old instance not the new one, so nothing will show up. If you can't wait, go to BaseDrawer and comment out the if (initialized) check.
     
  29. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Just released 1.2.5, sorry I should have released it earlier, it comes with some fixes and cool new features, mainly static fields/properties serialization (@CptTeacup :p) and exposure for readonly properties (properties with a getter only) - and just a reminder readonly fields are serializable as well. So we can write:
    Code (csharp):
    1.  
    2. [Serialize, Hide] private static int count;
    3. [Show] public static int Count { get { return count; } }
    4. public readonly uAction SomeEvent = new uAction();
    5.  
    @sGlorz let me know whether or not you still have your issue in this release
     
    Last edited: Dec 18, 2014
  30. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    I'll just wait, thanks.
     
  31. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @sGlorz I'm not sure if you missed my last message or maybe I wasn't clear/didn't state explicitly that I released 1.2.5 - Please see if it addresses your issue or not :)
     
    Last edited: Dec 18, 2014
  32. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    @vexe 1.2.5 did not correct the issue :(

    But, I know how to reproduce it easily:
    1/ Select the gameobject with ObjectDrawer
    2/ Start the game
    3/ Stop the game
    => ObjectDrawer info are not displayed

    To get it back:
    1/ Select any other GameObject
    2/ Start the game
    3/ Stop the game
    4/ Select the gameobject with ObjectDrawer
    => ObjectDrawer info are displayed

    By the way some remarks and questions:
    1/ Can you put the current version and history information in plugin root folder?
    2/ Can we move the plugin in any sub directories in Asset?
    3/ It would be great to keep open/close tab (category) states in object inspector when closing Unity
    4/ In my object drawer, whatever the width of the inspector, I have a horizontal scrollbar. (see image) How can I remove it?
     

    Attached Files:

  33. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @sGlorz I'm unable to reproduce with my current drawers. Can you send me the code for your drawer? (or code that replicates the issue)

    1- Will do.
    2- No. The "Plugins" folder has to be directly under "Assets"
    3- Hmm, didn't notice that. Although they should persist (they're stored in BetterEditorPrefs, which should technically serialize and have its values survive unity sessions) Will check it out.
    4- I've noticed that yeah. It seems to be caused by RabbitGUI, I'm not sure what's exactly causing it, it is indeed an inconvenience. Will try to investigate when I get the chance.
     
  34. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    Bug Found !

    Comming from my side:

    Code (CSharp):
    1.  
    2. public override void OnGUI()
    3. {
    4.         // No value, nothing to do
    5.         if (memberValue == null || gameObject == null) return;
    6. }
    7.  
    OnGUI() is called with gameObject == null :)
    But I need the gameObject, how can I have the gameObject linked to the drawer?
    Sometimes gameObject has the good value, sometimes not.
     
  35. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    gameObject can't be null, if it is, there's no drawer to begin with ;) (unless the drawer is leaked with a destroyed gameObject reference)- It's mostly likely that your memberValue is null. What are you targeting? - set your member value to some default value it it was null, if (memberValue == null) memberValue = CreateNewOrSomething();
     
  36. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    No, no, gameObject is null and memberValue is not null.
     
  37. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Something's not right. I need more information here. What is your drawer targeting? how about unityTarget? is it null too? and what kind of null is it? a null reference or a real unity null? i.e. in the debugger, does it appear a string literal "null" and can you collapse it? or your can't collapse it at all? - It would be helpful if you show me some code and explain your situation, please do that if you can.
     
  38. snw

    snw

    Joined:
    Mar 13, 2014
    Posts:
    42
    Hi vexe,

    I'm having a problem with the following scenario:
    I created a ScriptableObject named SO_Items. It's a BetterScriptableObject, implementing the interface IItems and has a property "items" (of type List<IItem>).
    Then I have some other ScriptableObjects named SO_Item01, SO_Item02 etc. Each of these is a BetterScriptableObject, implementing the interface IItem.

    My goal would be to be able to drag SO_Item01, SO_Item02 etc. into the "items"-property of the SO_Items-ScriptableObject. But the objects don't get accepted, i.e. the field keeps displaying: "null (IItem)" and "Member value is null".

    Is there a way to make this work?

    Oh, and if I use the selection pop-up by clicking the circle button next to an empty IItem-field and select SO_Item ("Unity types" tab), Unity crashes. Just found this out by accident :)

    I uploaded a test project (Assets folder should be enough, right?), in case you want to take a look. The relevant stuff can be found in the folders ScriptableObjects and Scripts.


    Cheers
     

    Attached Files:

    vexe likes this.
  39. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    gameObject is null
    unityTarget is not null

    Here is the "this" and memberValue in MSDEV watch:

    Code (CSharp):
    1.  
    2. -     this   {HitRuleDrawer}   HitRuleDrawer
    3. -     base   {HitRuleDrawer}   Vexe.Editor.Drawers.ObjectDrawer`1[[MovingElement+HitRule, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
    4. -     base   {HitRuleDrawer}   Vexe.Editor.Drawers.BaseDrawer
    5. -     attributes   System.Attribute[3]   System.Attribute[]
    6. +     [0]   {Vexe.Runtime.Types.SeqAttribute}   System.Attribute
    7. +     [1]   {Vexe.Runtime.Types.PerItemAttribute}   System.Attribute
    8. +     [2]   {Vexe.Runtime.Types.CategoryAttribute}   System.Attribute
    9.      foldout   false   System.Boolean
    10.      gameObject   null   UnityEngine.GameObject
    11. -     gui   {Vexe.Editor.GUIs.RabbitGUI}   Vexe.Editor.GUIs.BaseGUI
    12. +     base   {Vexe.Editor.GUIs.RabbitGUI}   Vexe.Editor.GUIs.BaseGUI
    13. +     LastRect   "(x:0.00, y:0.00, width:1.00, height:1.00)"   UnityEngine.Rect
    14.      allocatedMemory   false   System.Boolean
    15. +     blockStack   {System.Collections.Generic.Stack`1[[Vexe.Editor.GUIs.GUIBlock, Assembly-CSharp-Editor-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]}   System.Collections.Generic.Stack`1[[Vexe.Editor.GUIs.GUIBlock, Assembly-CSharp-Editor-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
    16. +     blocks   Count=16   System.Collections.Generic.List`1[[Vexe.Editor.GUIs.GUIBlock, Assembly-CSharp-Editor-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
    17. +     controls   Count=25   System.Collections.Generic.List`1[[Vexe.Editor.GUIs.GUIControl, Assembly-CSharp-Editor-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
    18.      currentPhase   Layout   Vexe.Editor.GUIs.RabbitGUI+GUIPhase
    19.      height   0f   System.Single
    20.      nextBlockIdx   16   System.Int32
    21.      nextControlIdx   0   System.Int32
    22.      pendingLayoutRequest   false   System.Boolean
    23.      pendingResetRequest   false   System.Boolean
    24.      prevInspectorWidth   0f   System.Single
    25. +     start   "(x:14.00, y:253.00, width:257.00, height:0.00)"   UnityEngine.Rect
    26. +     validRect   "(x:14.00, y:253.00, width:258.00, height:0.00)"   System.Nullable`1[[UnityEngine.Rect, UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
    27.      width   257f   System.Single
    28.      id   "8e16b715-c705-40a1-b1fb-737728d1de7dHitRule[]Hit Rules0"   System.String
    29.      initialized   true   System.Boolean
    30. -     member   "HitRule 0"   Vexe.Editor.EditorMember
    31. +     base   "HitRule 0"   Vexe.Editor.ArgMember
    32.      Index   0   System.Int32
    33. +     List   MovingElement+HitRule[1]   System.Collections.Generic.IList`1[[MovingElement+HitRule, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
    34.      Readonly   false   System.Boolean
    35. -     memberType   "MovingElement+HitRule"   System.Type
    36. +     base   "MovingElement+HitRule"   System.Type
    37. +     Assembly   "Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"   System.Reflection.Assembly
    38.      AssemblyQualifiedName   "MovingElement+HitRule, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"   System.String
    39. +     BaseType   "System.Object"   System.Type
    40.      ContainsGenericParameters   false   System.Boolean
    41.      DeclaringMethod   System.InvalidOperationException: DeclaringMethod can only be used on generic arguments   System.Reflection.MethodBase
    42. +     DeclaringType   "MovingElement"   System.Type
    43.      FullName   "MovingElement+HitRule"   System.String
    44. +     GUID   "00000000-0000-0000-0000-000000000000"   System.Guid
    45.      IsGenericParameter   false   System.Boolean
    46.      MemberType   NestedType   System.Reflection.MemberTypes
    47. +     Module   "Assembly-CSharp.dll"   System.Reflection.Module
    48.      Name   "HitRule"   System.String
    49.      Namespace   null   System.String
    50. +     ReflectedType   "MovingElement"   System.Type
    51. +     TypeHandle   {System.RuntimeTypeHandle}   System.RuntimeTypeHandle
    52. +     UnderlyingSystemType   "MovingElement+HitRule"   System.Type
    53. +     Non-Public members    
    54.      memberTypeName   "HitRule"   System.String
    55.      niceName   ""   System.String
    56. -     rawTarget   "Pestle (MovingElement)"   System.Object
    57. +     base   "Pestle (MovingElement)"   Vexe.Runtime.Types.BetterBehaviour
    58. +     HitRules   MovingElement+HitRule[1]   MovingElement+HitRule[]
    59. +     Path   UnityEngine.Vector3[2]   UnityEngine.Vector3[]
    60.      Status   Idle   MovingElement+MovingElementStatus
    61.      TextStatus   "Playing: False\nBackwards: False\nNo rule triggered\n"   System.String
    62. +     TriggerRules   MovingElement+TriggerRule[2]   MovingElement+TriggerRule[]
    63.      _ActiveTriggerRule   null   MovingElement+TriggerRule
    64. +     _AutoMoveRules   Count=0   System.Collections.Generic.List`1[[MovingElement+TriggerRule, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
    65. +     _ChainedRules   Count=2   System.Collections.Generic.List`1[[System.Collections.Generic.List`1[[MovingElement+TriggerRule, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
    66. +     _OriginalPosition   "(6.0, 7.1, 0.0)"   UnityEngine.Vector3
    67. +     _Tween   {DG.Tweening.Core.TweenerCore`3[[UnityEngine.Vector3, UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[DG.Tweening.Plugins.Core.PathCore.Path, DOTween, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[DG.Tweening.Plugins.Options.PathOptions, DOTween, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]}   DG.Tweening.Tween
    68. -     targetType   "MovingElement"   System.Type
    69. +     base   "MovingElement"   System.Type
    70. +     Assembly   "Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"   System.Reflection.Assembly
    71.      AssemblyQualifiedName   "MovingElement, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"   System.String
    72. +     BaseType   "Vexe.Runtime.Types.BetterBehaviour"   System.Type
    73.      ContainsGenericParameters   false   System.Boolean
    74.      DeclaringMethod   System.InvalidOperationException: DeclaringMethod can only be used on generic arguments   System.Reflection.MethodBase
    75.      DeclaringType   null   System.Type
    76.      FullName   "MovingElement"   System.String
    77. +     GUID   "00000000-0000-0000-0000-000000000000"   System.Guid
    78.      IsGenericParameter   false   System.Boolean
    79.      MemberType   TypeInfo   System.Reflection.MemberTypes
    80. +     Module   "Assembly-CSharp.dll"   System.Reflection.Module
    81.      Name   "MovingElement"   System.String
    82.      Namespace   null   System.String
    83.      ReflectedType   null   System.Type
    84. +     TypeHandle   {System.RuntimeTypeHandle}   System.RuntimeTypeHandle
    85. +     UnderlyingSystemType   "MovingElement"   System.Type
    86. +     Non-Public members    
    87. -     unityTarget   "Pestle (MovingElement)"   UnityEngine.Object
    88. +     base   "Pestle (MovingElement)"   Vexe.Runtime.Types.BetterBehaviour
    89. +     HitRules   MovingElement+HitRule[1]   MovingElement+HitRule[]
    90. +     Path   UnityEngine.Vector3[2]   UnityEngine.Vector3[]
    91.      Status   Idle   MovingElement+MovingElementStatus
    92.      TextStatus   "Playing: False\nBackwards: False\nNo rule triggered\n"   System.String
    93. +     TriggerRules   MovingElement+TriggerRule[2]   MovingElement+TriggerRule[]
    94.      _ActiveTriggerRule   null   MovingElement+TriggerRule
    95. +     _AutoMoveRules   Count=0   System.Collections.Generic.List`1[[MovingElement+TriggerRule, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
    96. +     _ChainedRules   Count=2   System.Collections.Generic.List`1[[System.Collections.Generic.List`1[[MovingElement+TriggerRule, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
    97. +     _OriginalPosition   "(6.0, 7.1, 0.0)"   UnityEngine.Vector3
    98. +     _Tween   {DG.Tweening.Core.TweenerCore`3[[UnityEngine.Vector3, UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[DG.Tweening.Plugins.Core.PathCore.Path, DOTween, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[DG.Tweening.Plugins.Options.PathOptions, DOTween, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]}   DG.Tweening.Tween
    99. -     Static members    
    100. +     foldouts   {Vexe.Editor.Foldouts}   Vexe.Editor.Foldouts
    101. +     prefs   "BetterEditorPrefs (Vexe.Runtime.Types.BetterPrefs)"   Vexe.Runtime.Types.BetterPrefs
    102. -     memberValue   {MovingElement+HitRule}   MovingElement+HitRule
    103.      AppliedDamage   ExplodeHit   MovingElement+AppliedDamage
    104.      Damage   0f   System.Single
    105.      DamageForce   10f   System.Single
    106.      ExecRule   true   System.Boolean
    107.      Moving   NormalPath   MovingElement+MovingStatus
    108.      TriggerRuleNumber   1   System.Int32
    109.  
    110.  
     
  40. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    Small test :

    Code (CSharp):
    1.  
    2. Debug.Log("unityTarget => " + unityTarget);
    3. Debug.Log("unityTarget as Component => " + (unityTarget as Component));
    4. Debug.Log("(unityTarget as Component).gameObject => " + (unityTarget as Component).gameObject);
    5. Debug.Log("gameObject == null =>" + (gameObject == null));
    Log results:

    unityTarget => Pestle (MovingElement)
    unityTarget as Component => Pestle (MovingElement)
    (unityTarget as Component).gameObject => Pestle (UnityEngine.GameObject)
    gameObject == null =>True

    With
    Code (CSharp):
    1.  
    2. protected GameObject gameObject
    3. {
    4.        get
    5.        {
    6.          var component = unityTarget as Component;
    7.          return component == null ? null : component.gameObject;
    8.        }
    9. }
    10.  

    I don't understand, it should work...
     
    vexe likes this.
  41. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Took a little nap :3 - @sGlorz that's tough to swallow isn't it? welcome to writing editor codes :D - Use a single HitRule instead of an array and you won't see this behaviour, which kind of narrows down the issue to how I'm creating EditorMembers to represent the array's elements, def a bug. Will fix asap.

    Already fixed the horizontal bar issue, and the categories not persisting.

    @snw of course it's possible, it's just about finding the time, sitting there and writing the code :p - will implement and fix in next version.
     
  42. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @sGlorz just released 1.2.6 - it should address your issue. Frankly, I've never seen anything like this, what an abnormal phenomena ... For me it was happening when I exit playmode, it seems that there's no assembly reload that happens when you exit, so the drawers cache remain, which means the same drawer instance that drew your member in playmode, will now be used to draw in editor, which means, the same unityTarget that was assigned to the drawer in playmode, will now be used when you compare it to null, or get gameObject, etc -- only thing that makes sense to me, is that Unity is doing something in the == that returns a null in this case.... Anyways, the way this is fixed, is you either reset the drawers cache when you exit playmode, I tried that, but it seems that it get cleared after a single OnGUI call, which would throw a nullrefexc if you were using that drawer's unityTarget - I couldn't find a way to clear it before that happens. The other way, which was to update the unityTarget everytime I get my sequence elements (see SequenceDrawer.GetElement) - Does this make sense? Let me know what happens.

    @snw I've implemented drag-drop for interfaces fields, you should be able to drag-drop your ScriptableObjects now. As for the crash, it was happening because it was trying to create an instance of your object and attach it to a gameObject, one does not simply do that :D - So I limited the unity types instantiation to MonoBehaviours only, I didn't want to create a new ScriptableObject and an asset for it, I don't want to assume anything about where you'd want your asset to be. Instead, you should already have an asset file and you just drop it in the interface field. Hope that's OK :)

    Sorry if I caused any inconvenience :|
     
  43. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    What you explain makes sense to me. I've installed the version 1.2.6 and it works. I'm also pleased to have my drawer open/close state saved and to see the history file in Plugins/Vexe.

    Thanks for your support.
     
  44. snw

    snw

    Joined:
    Mar 13, 2014
    Posts:
    42
    Great! You should have a Paypal button somewhere for coffee or beer donations :D
     
  45. Jlpeebles

    Jlpeebles

    Joined:
    Oct 21, 2012
    Posts:
    54
    Do you intend to implement KickassDelegate-like functionality? Also what about using methods as parameters when invoking a delegate? Is that even realistic?
     
  46. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @Jlpeebles KD-like delegates and extension methods are probably the only things I'm missing in VFW delegates. Thing is, uFAction was ridiculously sophisticated, in VFW I wanted to keep things as simple as possible as best as I can if I could help it. I noticed in my personal development I don't hugely demand KD-like delegates, most the times It's a finite number/ specific type of parameters that I'm interested in... If there's a demand for KD, I'll try to think of a clean way to implement it when I have time

    As for methods as params, I think you mean delegates as params? yeah sure
    Code (csharp):
    1.  
    2. public uAction<Action<string>> onSomething; // you could use uAction for the nested one if you care about invoking the delegate from the editor, cause Actions are not exposed, but uActions are
    3.  
    4. public void SomethingHandler(Action<string> method)  { ... }
    5.  
    6. private void PassMe(string str) { ... }
    7.  
    8. // somewhere else....
    9. onSomething.Add(SomethingHandler);
    10. // ....
    11. onSomething.Invoke(PassMe);
    12.  
    Is it realistic? depends on what you're doing, it is not often that you'd need to do something like this but hey, you gotta do what you gotta do.
     
    Last edited: Dec 28, 2014
  47. Inok

    Inok

    Joined:
    Feb 5, 2014
    Posts:
    16
    vexe, can i save for example runtime instantiated prefab, so when i load "save" i will see instantiated gameobject in hierarchy tab? Sorry for primitive question but i must know your serialization system can serialize all or not all things.
     
  48. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Hi @Inok, thanks for dropping by.

    You can save whatever data you want. But what do you mean with "when I load 'save'"? - Can you elaborate more on what exactly are you trying to do so I can help you better? - You have a prefab, and you want to save it to a file.. or?
     
    Last edited: Jan 6, 2015
  49. Inok

    Inok

    Joined:
    Feb 5, 2014
    Posts:
    16
    I want save prefab clone instantiated runtime via code. So 1) This instance appear in scene hierarchy at runtime; 2) i press "make save of scene"; 3) i press "load saved scene" and i will see that this prefab instance(clone) exist in hierarchy of scene. Hope this words more clear. Sorry English is not my native language.
     
  50. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Ah, you're talking about the SaveSystem I mentioned earlier and posted that demo video about? or are you asking how to do it with the current VFW version?