Search Unity

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

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

  1. J_P_

    J_P_

    Joined:
    Jan 9, 2010
    Posts:
    1,027
    Last edited: Feb 17, 2015
  2. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Hi there JTown! - That's how pretty much all the drawers work. If you just take a look at any of them, it's easy to figure out. In your case, just inherit ObjectDrawer<YourType> - Every drawer has a BaseGUI instance that you could use for your drawing, the syntax is very similar to GUILayout stuff but I use a custom layout algorithm. Just skimming through some of the drawers you'll get a solid idea how to work your way around.

    I use IDisposable heavily in my gui I think it makes things neat. So instead of:
    Code (csharp):
    1.  
    2. GUILayout.BeginHorizontal();
    3. {
    4.     // code...
    5. }
    6. GUILayout.EndHorizontal();
    7.  
    you do:

    Code (csharp):
    1.  
    2. using (gui.Horizontal())
    3. {
    4.    // code...
    5. }
    6.  
     
  3. bigdaddy

    bigdaddy

    Joined:
    May 24, 2011
    Posts:
    153
    Has anyone tried VFW with IL2CPP in 4.6.2? I think there is a problem:

    Code (CSharp):
    1.  
    2. (lldb) bt
    3. * thread #23: tid = 0x3b03, 0x017a6bd8 dragonsdodge`il2cpp::vm::Class::FromIl2CppType(type=0xe24dd014) + 12 at Class.cpp:47, stop reason = EXC_BAD_ACCESS (code=1, address=0xe24dd01a)
    4.   * frame #0: 0x017a6bd8 dragonsdodge`il2cpp::vm::Class::FromIl2CppType(type=0xe24dd014) + 12 at Class.cpp:47
    5.     frame #1: 0x0177fb2c dragonsdodge`il2cpp::icalls::mscorlib::System::MonoCustomAttrs::IsDefinedInternal(obj=<unavailable>, attr_type=0x0082d608) + 40 at MonoCustomAttrs.cpp:70
    6.     frame #2: 0x00a77ffc dragonsdodge`MonoCustomAttrs_IsDefinedInternal_m36894(__this=0x00000000, ___obj=0x0d8bebd0, ___AttributeType=0x0082d608) + 128 at Bulk_mscorlib_5.cpp:53808
    7.     frame #3: 0x00a77d04 dragonsdodge`MonoCustomAttrs_IsDefined_m36893(__this=0x00000000, ___obj=0x0d8bebd0, ___attributeType=0x0082d608, ___inherit=false) + 364 at Bulk_mscorlib_5.cpp:53717
    8.     frame #4: 0x00a7c374 dragonsdodge`MonoType_IsDefined_m36934(__this=0x0d8bebd0, ___attributeType=0x0082d608, ___inherit=false) + 104 at Bulk_mscorlib_5.cpp:56814
    9.     frame #5: 0x0097c124 dragonsdodge`VirtFuncInvoker2<bool, Type_t392*, bool>::Invoke(method=0x02711fe4, obj=0x0d8bebd0, p1=0x0082d608, p2=false) + 92 at GeneratedVirtualInvokers.h:64
    10.     frame #6: 0x0082d664 dragonsdodge`VexeTypeExtensions_IsDefined_m21681(__this=0x0d8c3f40, ___minfo=0x0d8bebd0, ___type=0x0082d608) + 92 at Bulk_RuntimeExtensions_0.cpp:6721
    11.     frame #7: 0x0071fe40 dragonsdodge`Func2_Invoke_m21636(__this=0x0757c4d0, ___arg1=0x0d8bebd0) + 100 at Bulk_Generics_73.cpp:373
    12.     frame #8: 0x0097c00c dragonsdodge`VirtFuncInvoker1<bool, Object_t6*>::Invoke(method=0x024c7380, obj=0x0757c4d0, p1=0x0d8bebd0) + 76 at GeneratedVirtualInvokers.h:42
    13.     frame #9: 0x00bb15ac dragonsdodge`Enumerable_Any_m21640_gshared(__this=0x00000000, ___source=0x07574f20, ___predicate=0x0757c4d0, mrgctx=0x027f4ea8) + 360 at GenericMethods11.cpp:26738
    14.     frame #10: 0x00241f30 dragonsdodge`Enumerable_Any_m21639(__this=0x00000000, p0=0x07574f20, p1=0x0757c4d0) + 60 at Bulk_Assembly-CSharp-firstpass_5.cpp:376
    15.     frame #11: 0x00241fbc dragonsdodge`SerializationLogic_IsSerializable_m19982(__this=0x0d8c3f80, ___field=0x0d8c3f40) + 128 at Bulk_Assembly-CSharp-firstpass_5.cpp:1246
    16.     frame #12: 0x0024265c dragonsdodge`SerializationLogic_IsSerializable_m19980(__this=0x0d8c3f80, ___member=0x0757c930) + 152 at Bulk_Assembly-CSharp-firstpass_5.cpp:1050
    17.     frame #13: 0x00738d90 dragonsdodge`Func2_Invoke_m60914(__this=0x0757c508, ___arg1=0x0757c930) + 100 at Bulk_Generics_75.cpp:12513
    18.     frame #14: 0x0097c00c dragonsdodge`VirtFuncInvoker1<bool, Object_t6*>::Invoke(method=0x024f1170, obj=0x0757c508, p1=0x0757c930) + 76 at GeneratedVirtualInvokers.h:42
    19.     frame #15: 0x006dbc60 dragonsdodge`CreateWhereIteratorcIterator1D1_MoveNext_m58107_gshared(__this=0x0d8bbe70) + 588 at Bulk_Generics_66.cpp:24697
    20.     frame #16: 0x00738ea0 dragonsdodge`CreateWhereIteratorcIterator1D1_MoveNext_m60922(__this=0x0d8bbe70) + 24 at System_Core_System_Linq_Enumerable_U003CCreateWhereIteratorU_2MethodDeclarations.h:48
    21.     frame #17: 0x00113ab8 dragonsdodge`InterfaceFuncInvoker0<bool>::Invoke(method=0x02718a50, obj=0x0d8bbe70) + 64 at GeneratedInterfaceInvokers.h:20
    22.     frame #18: 0x0057f150 dragonsdodge`List1_AddEnumerable_m39857_gshared(__this=0x0d8be8d0, ___enumerable=0x0d8bbe70) + 396 at Bulk_Generics_2.cpp:21900
    23.     frame #19: 0x00711e94 dragonsdodge`List1_AddEnumerable_m59308(__this=0x0d8be8d0, ___enumerable=0x0d8bbe70) + 32 at mscorlib_System_Collections_Generic_List_1_gen_64MethodDeclarations.h:142
    24.     frame #20: 0x0057d45c dragonsdodge`List1_ctor_m39822_gshared(__this=0x0d8be8d0, ___collection=0x0d8bbe70) + 268 at Bulk_Generics_2.cpp:21267
    25.     frame #21: 0x00711b7c dragonsdodge`List1_ctor_m59289(__this=0x0d8be8d0, ___collection=0x0d8bbe70) + 32 at mscorlib_System_Collections_Generic_List_1_gen_64MethodDeclarations.h:46
    26.     frame #22: 0x00b36330 dragonsdodge`Enumerable_ToList_m5217_gshared(__this=0x00000000, ___source=0x0d8bbe70, mrgctx=0x027f97d0) + 156 at GenericMethods1.cpp:1049
    27.     frame #23: 0x0024115c dragonsdodge`Enumerable_ToList_m21698(__this=0x00000000, p0=0x0d8bbe70) + 52 at Bulk_Assembly-CSharp-firstpass_5.cpp:285
    28.     frame #24: 0x00240ecc dragonsdodge`SerializationLogic_GetSerializableMembers_m19975(__this=0x0d8c3f80, ___type=0x0d8beb28, ___target=0x00000000) + 364 at Bulk_Assembly-CSharp-firstpass_5.cpp:683
    29.     frame #25: 0x00242f0c dragonsdodge`SerializationLogic_getGetMemoizedSerializableMembersmA2_m19985(__this=0x0d8c3f80, ___type=0x0d8beb28) + 36 at Bulk_Assembly-CSharp-firstpass_5.cpp:1426
    30.     frame #26: 0x0067d31c dragonsdodge`Func2_Invoke_m54055_gshared(__this=0x0757cb60, ___arg1=0x0d8beb28) + 100 at Bulk_Generics_56.cpp:24412
    31.     frame #27: 0x00712a04 dragonsdodge`Func2_Invoke_m21274(__this=0x0757cb60, ___arg1=0x0d8beb28) + 32 at System_Core_System_Func_2_gen_9MethodDeclarations.h:32
    32.     frame #28: 0x0097cae4 dragonsdodge`VirtFuncInvoker1<Object_t6*, Object_t6*>::Invoke(method=0x024a2d20, obj=0x0757cb60, p1=0x0d8beb28) + 76 at GeneratedVirtualInvokers.h:42
    33.     frame #29: 0x00718a34 dragonsdodge`cDisplayClass42_Memoizeb3_m59580_gshared(__this=0x0d8beb40, ___n=0x0d8beb28) + 176 at Bulk_Generics_71.cpp:8258
    34.     frame #30: 0x0072e8a4 dragonsdodge`cDisplayClass42_Memoizeb3_m60562(__this=0x0d8beb40, ___n=0x0d8beb28) + 32 at RuntimeExtensions_Vexe_Runtime_Extensions_DelegateExtensions_4MethodDeclarations.h:24
    35.     frame #31: 0x0067d31c dragonsdodge`Func2_Invoke_m54055_gshared(__this=0x0757caf0, ___arg1=0x0d8beb28) + 100 at Bulk_Generics_56.cpp:24412
    36.     frame #32: 0x00712a04 dragonsdodge`Func2_Invoke_m21274(__this=0x0757caf0, ___arg1=0x0d8beb28) + 32 at System_Core_System_Func_2_gen_9MethodDeclarations.h:32
    37.     frame #33: 0x0023fa80 dragonsdodge`VirtFuncInvoker1<List1_t7517*, Type_t392*>::Invoke(method=0x024a2d20, obj=0x0757caf0, p1=0x0d8beb28) + 76 at GeneratedVirtualInvokers.h:42
    38.     frame #34: 0x00244cc0 dragonsdodge`BetterSerializer_DeseiralizeDataIntoTarget_m20001(__this=0x0d8bee40, ___target=0x0757cfc0, ___data=0x0d8beeb8) + 184 at Bulk_Assembly-CSharp-firstpass_5.cpp:3527
    39.     frame #35: 0x0024e250 dragonsdodge`BetterBehaviour_Deserialize_m6444(__this=0x0757cfc0) + 64 at Bulk_Assembly-CSharp-firstpass_5.cpp:24642
    40.     frame #36: 0x00113820 dragonsdodge`VirtActionInvoker0::Invoke(method=0x01f29f54, obj=0x0757cfc0) + 64 at GeneratedVirtualInvokers.h:9
    41.     frame #37: 0x0024e1a4 dragonsdodge`BetterBehaviour_OnAfterDeserialize_m6442(__this=0x0757cfc0) + 48 at Bulk_Assembly-CSharp-firstpass_5.cpp:24617
    42.     frame #38: 0x00a9714c dragonsdodge`RuntimeInvoker_Void_t149(method=0x01f2a884, obj=0x0757cfc0, args=0x0d857830) + 60 at GeneratedInvokers.cpp:12
    43.     frame #39: 0x017b7f10 dragonsdodge`il2cpp::vm::Runtime::Invoke(MethodInfo*, void*, void**, Il2CppObject**) + 156
    44.     frame #40: 0x01207798 dragonsdodge`ScriptingInvocationNoArgs::Invoke(this=0x0d85792c, exception=0x0d857920) + 196 at ScriptingInvocationNoArgs.cpp:99
    45.     frame #41: 0x012076cc dragonsdodge`ScriptingInvocationNoArgs::Invoke(this=<unavailable>) + 36 at ScriptingInvocationNoArgs.cpp:83
    46.     frame #42: 0x011bc814 dragonsdodge`void InvokeMethod<StreamedBinaryRead<false> >(args=<unavailable>, runtimeInfo=<unavailable>) + 68 at BuildSerializationCommandQueueFor.cpp:26
    47.     frame #43: 0x011bef28 dragonsdodge`void ExecuteSerializationCommands<StreamedBinaryRead<false> >(dynamic_array<SerializationCommand, 4ul> const&, StreamedBinaryRead<false>&, GeneralMonoObject const&) [inlined] SerializationCommand::Execute(runtimeInfo=0x01f93f01) const + 148 at SerializationCommands.h:81
    48.     frame #44: 0x011bef1c dragonsdodge`void ExecuteSerializationCommands<StreamedBinaryRead<false> >(dynamic_array<SerializationCommand, 4ul> const&, StreamedBinaryRead<false>&, GeneralMonoObject const&) [inlined] void ExecuteSerializationCommands<StreamedBinaryRead<false> >(commandProvider=0x1d16a830, transfer=<unavailable>, instance=<unavailable>) + 72 at SerializationCommands.h:220
    49.     frame #45: 0x011beed4 dragonsdodge`void ExecuteSerializationCommands<StreamedBinaryRead<false> >(commands=<unavailable>, transfer=<unavailable>, instance=<unavailable>) + 64 at SerializationCommands.h:228
    50.     frame #46: 0x011bea2c dragonsdodge`void TransferScriptingObject<StreamedBinaryRead<false> >(transfer=<unavailable>, instance=<unavailable>, klass=<unavailable>, monoScriptCache=<unavailable>) + 296 at TransferScriptingObject.cpp:88
    51.     frame #47: 0x011f9dfc dragonsdodge`void MonoBehaviour::TransferEngineAndInstance<StreamedBinaryRead<false> >(this=<unavailable>, transfer=<unavailable>) + 96 at MonoBehaviourSerialization.cpp:52
    52.     frame #48: 0x011f9b28 dragonsdodge`MonoBehaviour::VirtualRedirectTransfer(this=<unavailable>, transfer=<unavailable>) + 132 at MonoBehaviourSerialization.cpp:115
    53.     frame #49: 0x012476b4 dragonsdodge`SerializedFile::ReadObject(this=0x1e2e5ee0, fileID=45, instanceId=<unavailable>, mode=<unavailable>, didChangeTypeTree=0x01c8ca34, outObjectPtr=<unavailable>, isPersistent=<unavailable>, oldTypeTree=<unavailable>) + 740 at SerializedFile.cpp:1325
    54.     frame #50: 0x0123a44c dragonsdodge`PersistentManager::LoadFileCompletelyThreaded(this=0x1d92fe30, pathname=<unavailable>, fileIDs=<unavailable>, instanceIDs=<unavailable>, size=<unavailable>, loadProgress=0x00000024, loadScene=<unavailable>) + 1168 at PersistentManager.cpp:1450
    55.     frame #51: 0x011a2034 dragonsdodge`PreloadLevelOperation::Perform(this=0x1e3920f0) + 1424 at PreloadManager.cpp:686
    56.     frame #52: 0x011a0d04 dragonsdodge`PreloadManager::Run(this=0x1e235780) + 536 at PreloadManager.cpp:239
    57.     frame #53: 0x011a0ae0 dragonsdodge`PreloadManager::Run(managerPtr=0x39883ce1) + 40 at PreloadManager.cpp:186
    58.     frame #54: 0x0126dd0c dragonsdodge`Thread::RunThreadWrapper(ptr=0x1e235780) + 64 at Thread.cpp:40
    59.     frame #55: 0x3a2830e0 libsystem_c.dylib`_pthread_start + 308
    60.     frame #56: 0x3a282fa8 libsystem_c.dylib`thread_start + 8
    61. (lldb)
    62.  
     
  4. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Oh boy... that's nasty. There's too much going on there. It doesn't seem to like reflection. Something's coming from MethodInfo.IsDefined. Haven't tried il2cpp myself yet, but it seems like a bug to me. If you read their release notes there's tons of reflection fixes. Maybe try to run with some code that does IsDefined on a MethodInfo see if it bugs or not.
     
  5. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    I don't want to turn this thread into a conversation about il2cpp or anything unrelated to vfw, there's already tons of threads about the subject. But I just want to say this, I really don't get what they're doing. Like look at us, we're battling the garbage collector because it hurts performance. What's the point of having a gc if we're trying our best not to let it do its work?... So C# runtime perf lags behind C/C++, the solution they came up with was to add yet 'another' level of indirection and write a sophisticated, very complex, error prone, buggy system that converts il to cpp... why not just let us write cpp? we're game programmers, we're low-level people, so why not let us operate at that level? Maybe I'm being pessimistic, I just don't see how they'll be able to pull off something this complex if they can't implement a decent, 'usable' editor?
     
  6. bigdaddy

    bigdaddy

    Joined:
    May 24, 2011
    Posts:
    153
    I'm packaging up my project to send to Unity for them to work it out.

    While I do get nervous about converts if my only option was to write C++ then I wouldn't use Unity. I just don't like the C++ programming.
     
  7. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    Preach it, brother! I wrote almost the same rant when I heard that their "solution" to the broken GC and the license issues with Xamarin was to basically reinvent .NET from the ground up.

    The much better solution in my mind would be to just pay the license fees that Xamarin wants from them and update to a newer version of Mono. I don't know how much Xamarin was asking, but it can't be that much more than paying an entire team of developers for five years to write a new compiler from scratch.
     
  8. MaDDoX

    MaDDoX

    Joined:
    Nov 10, 2009
    Posts:
    764
    For the record, I trust Unity to do a better job than Xamarim at garbage collection any day. It's not as if the latest (updated) Mono versions pull off some GC performance miracle. Besides, building their own back end tools (which, according to some Twits I got from devs, will take some time to fully replace Mono) means they'll be able to optimize instantiation and de-instatiation of game objects in a way that's ideal for games, something a general-purpose platform will never focus on.
     
  9. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    Yeah, I don't. Xamarin is an entire company dedicated to one thing: replicating .NET, and they have the backing of Microsoft, a full time staff, a bigger budget, and have consistently kept up with the current version of .NET, even the new unreleased version. Unity is a company that is doing fifty different things at once, has a reputation for always moving on to new things instead of fixing older broken things, has a hostile relationship with Xamarin, and is still literally a decade behind the current version of .NET despite "working on it" for years. IL2CPP currently only works on ONE of their ten supported platforms, and only just barely, and there is no timetable on when it will ever actually be completed on iOS, much less pushed to all the other platforms, so I have no doubt that by the time they get their .NET 3.5 version to PC, Microsoft and Xamarin will already be releasing .NET 7.

    Buuuuut we're totally derailing VFW's thread. Sorry, it's just a sore spot for me since every non-Unity project I've worked on is almost always enjoying the benefits of the latest versions of .NET, and I hate having to be so far behind the current paradigm.
     
  10. supagu

    supagu

    Joined:
    Nov 29, 2014
    Posts:
    7
    Hi Vexe, this plugin is a life saver.

    Now I have just bumped into a problem I dont know if I have done it right:

    [RequiredFromThis(0, true), Inline(1, HideTarget = true)]
    public AudioSource MyAudioSource;

    I want MyAudioSource to be automatically created, then displayed as inline to the user.
    But I get an error saying "Please assign a target to inline"
    I am unsure what this means
     
  11. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @supagu sorry didn't get notified of your post.

    It means that your AudioSource reference is not assigned. I've changed the requirements system a bit. In order for your requirements to be resolved, you need to mark your script with [HasRequirements] - when you do that, you can either resolve them manually by pressing the button under the script header, or automatically if you enable automatic requirements resolution under Tools/Vexe/Requirements

    Notice even if you do that, if you try to inline an AudioSource you'll get errors that's cause currently I don't have it supported for inline drawing. So just go to InlineAttributeDrawer.cs and add this dictionary entry:
    Code (csharp):
    1.  
    2.         {
    3.            typeof(AudioSource), (target, gui) =>
    4.            {
    5.              RecursiveDrawer.DrawRecursive(target, gui, id, target,
    6.                "mute", "bypassEffects", "bypassListenerEffects", "bypassReverbZones", "playOnAwake", "loop");
    7.  
    8.              var source = target as AudioSource;
    9.              source.priority = gui.IntSlider("Priority", source.priority, 0, 128);
    10.              source.volume = gui.FloatSlider("Volume", source.volume, 0f, 1f);
    11.              source.pitch = gui.FloatSlider("Pitch", source.pitch, -3f, 3f);
    12.            }
    13.          },
    14.  


    Notice not all of it is drawn - You might have read it but I use a different gui layouting system so to inline a component that uses the Unity layout system we'd have to write the equivalent drawer for it ourselves (which is what I'm doing in that dictionary you see in the inline drawer file) - You don't need to do this to inline BetterBehaviours.
     
  12. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    And wrap those sliders with a using (gui.Indent()) { ... } to align them correctly
     
  13. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    So I've been learning IL recently. I wrote a fast dynamic reflection system similar but better than Fasterflect. It pretty much uses the same idea of generating IL code to set/get fields/properties, call methods and invoke constructors. The thing though, you don't need to deal with structs in any special way. Fasterflect requires you to wrap them in a ValueTypeHolder, even when I did that, and couldn't get the delegate API to work... Plus, Fasterflect is more than what we need, it's a couple of tens of files, while my system is just a single file with ~500 lines of code. Here's some benchmarks (each measurement is running 1000000 times):



    I did some simple benchmarks against Fasterflect, and it's 'slightly' even faster (probably because the IL I'm emitting is simpler/less)
    I kept the API calls the same so it's easier for me to migrate. Might change them for something shorter.

    This will be available in VFW 1.3 in my vRuntime.dll - so no source code. I might release it dirty cheap if anybody's interested. :)
     
    Last edited: Feb 25, 2015
    twobob likes this.
  14. andrew-lukasik

    andrew-lukasik

    Joined:
    Jan 31, 2013
    Posts:
    249
    (Unity 5f3) Hi. I came across strange issue - prefab fields reset to nulls exactly when I hit Play (but not all of them GameObject and Transform seems to be unaffected). What am I doing wrong here?
    Those fields looks like this:
    Code (CSharp):
    1. [SerializeField] private INeedCrew _isCrewMember = null;
    2. [SerializeField] private Weapon[] _weapons = new Weapon[0];
    btw.: other than that I love what I saw. Dictionaries <3 Interfaces<3 nice integration with existing gui <3
     
  15. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Hey andrew! Dude I love your gravatar lol it's really so damn cute ^__^

    I haven't yet upgraded to Unity 5 so unfortunately I can't really tell what's up. Can you try 4.6.1 just to see if the issue is there? - And, I prefer you use [Serialize] instead of [SerializeField] - because if you use SerializeField that means your field is going to be serialized by Unity (if it was an accepted serializable type by it) and VFW - But if you use Serialize it would only be serialized once by VFW - just a little overhead that you could avoid. - And, you're inheriting BetterBehaviour right?

    Edit: I just noticed 4.6.3 is out. I said 4.6.1 because there was a serialization bug in 4.6.2 - I don't know if they addressed that in 4.6.3 or in some patch.

    Edit: Started watching that show, "Chi's sweet home" hilarious lol - the ultimate cuteness. brutally adorable
     
    Last edited: Feb 25, 2015
  16. andrew-lukasik

    andrew-lukasik

    Joined:
    Jan 31, 2013
    Posts:
    249
    I inherited from Vexe.Runtime.Types.BetterBehaviour and tested [Vexe.Runtime.Types.BetterBehaviour.Serialize] but it changed nothing on this issue. But it's ok - I will wait for Unity 5-compatible version (time probably spent weeping and crying it's not out yet)

    Thanks for your reply Vexe! yes Chi is super^2 charming :D
     
  17. EF

    EF

    Joined:
    Jul 8, 2012
    Posts:
    7
    Just started working with VFW but that's one of the greatest frameworks for Unity I worked with. Very well designed.
    One thing that I can't seem to figure out is serializing to an external file. I'm trying to save an object with all it's children to a file(and then load this file in game on mobiles).

    I tried using BetterSerializer, but calling Serialize() throws errors.
    Code (CSharp):
    1. [Show]
    2.     public void Serialize()
    3.     {
    4.         BetterSerializer serializer = new BetterSerializer();
    5.      
    6.         string d = Serializer.Serialize(this.gameObject);
    7.         SaveToFile(d);
    8.     }
    error:
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. Vexe.Runtime.Serialization.UnityObjectConverter.TrySerialize (object,FullSerializer.fsData&,System.Type) (at Assets/Plugins/Vexe/Runtime/Serialization/Serializers/UnityObjectConverter.cs:22)
    3. FullSerializer.fsSerializer.InternalSerialize_4_Converter (object,System.Type,FullSerializer.fsData&) (at c:/Users/vexe/Desktop/MyExtensionsAndHelpers/Solution/FullSerializer/Source/fsSerializer.cs:526)
    4. FullSerializer.fsSerializer.InternalSerialize_3_ProcessVersioning (object,System.Type,FullSerializer.fsData&) (at c:/Users/vexe/Desktop/MyExtensionsAndHelpers/Solution/FullSerializer/Source/fsSerializer.cs:521)
    5. FullSerializer.fsSerializer.InternalSerialize_2_Inheritance (System.Type,System.Type,object,FullSerializer.fsData&) (at c:/Users/vexe/Desktop/MyExtensionsAndHelpers/Solution/FullSerializer/Source/fsSerializer.cs:464)
    6. FullSerializer.fsSerializer.InternalSerialize_1_ProcessCycles (System.Type,object,FullSerializer.fsData&) (at c:/Users/vexe/Desktop/MyExtensionsAndHelpers/Solution/FullSerializer/Source/fsSerializer.cs:444)
    7. FullSerializer.fsSerializer.TrySerialize (System.Type,object,FullSerializer.fsData&) (at c:/Users/vexe/Desktop/MyExtensionsAndHelpers/Solution/FullSerializer/Source/fsSerializer.cs:397)
    8. Vexe.Runtime.Serialization.BetterSerializer.Serialize (System.Type,object,object) (at Assets/Plugins/Vexe/Runtime/Serialization/Serializers/BetterSerializer.cs:115)
    9. Vexe.Runtime.Serialization.BetterSerializer.Serialize (object,object) (at Assets/Plugins/Vexe/Runtime/Serialization/Serializers/BetterSerializer.cs:124)
    10. Vexe.Runtime.Serialization.BetterSerializer.Serialize (object) (at Assets/Plugins/Vexe/Runtime/Serialization/Serializers/BetterSerializer.cs:129)
    11. Level.Serialzie () (at Assets/Scripts/Core/Level.cs:27)
    12. (wrapper dynamic-method) Level.invoke (object,object[]) <IL 0x00006, 0x0005f>
    13. Vexe.Editor.Drawers.MethodDrawer.Header () (at Assets/Plugins/Editor/Vexe/Drawers/API/Core/MethodDrawer.cs:104)
    14. Vexe.Editor.Drawers.MethodDrawer.OnGUI () (at Assets/Plugins/Editor/Vexe/Drawers/API/Core/MethodDrawer.cs:83)
    15. Vexe.Editor.GUIs.BaseGUI.Member (System.Reflection.MemberInfo,object,UnityEngine.Object,string,bool) (at Assets/Plugins/Editor/Vexe/GUIs/BaseGUI/Controls/Members.cs:25)
    16. Vexe.Editor.Internal.MembersCategory.Draw (UnityEngine.Object) (at Assets/Plugins/Editor/Vexe/Editors/Internal/MembersCategory.cs:124)
    17. Vexe.Editor.Editors.BaseEditor.GUICode () (at Assets/Plugins/Editor/Vexe/Editors/BaseEditor.cs:362)
    18. Vexe.Editor.GUIs.RabbitGUI.OnGUI (System.Action,UnityEngine.Vector2) (at Assets/Plugins/Editor/Vexe/GUIs/RabbitGUI/RabbitGUI.cs:126)
    19. Vexe.Editor.Editors.BaseEditor.OnInspectorGUI () (at Assets/Plugins/Editor/Vexe/Editors/BaseEditor.cs:121)
    20. UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor,int,bool,bool&,UnityEngine.Rect&,bool) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/Inspector/InspectorWindow.cs:1093)
    21. UnityEditor.DockArea:OnGUI()
    22.  
    Using VFW 1.2.9p1.

    Cheers!
     
  18. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Hi EF! - When it comes to UnityObjects VFW doesn't literally serialize them to bytes of data. It basically has a list of UnityObjects serialized by 'Unity' so any time VFW come across a UnityObject it just adds it to that list, and let Unity handle the serialization of its own objects. The purpose is to have our data persist assembly reloads - We let Unity serialize its own objects, and we handle anything else it doesn't handle.

    What you're getting is FullSerializer complaining it doesn't know how to handle GameObject. You can achieve exactly what you want if you use the Save System - which again, I haven't yet released because FullSerializer allocates a lot, and so I'm writing my own binary serializer. I sent you a pm.
     
  19. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Best thing about Launch of Unity 5 is that it's already working on PS Vita, so we can get our hands now on this nice plugin here :D
     
  20. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    I wanted to know if it's ok to use it with Unity 5. Imported the plugin and allowed Unity to migrate the code. After it was finished I ran some of the VFW Examples and everything seems to work.
     
  21. Deleted User

    Deleted User

    Guest

    Looks awesome but what do you mean when you say "no multi-object editing"?
     
  22. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @BTStone that's great. I've had some users use it in 5 beta, there were a few things that needed fixing but other than that it worked fine. I will release an official patch soon that will play well with Unity5, just fighting some bugs atm.

    @supremegrandruler If you select multiple BetterBehaviours/BetterScriptableObjects you can't multi-edit them
     
    Last edited: Mar 4, 2015
  23. SuperManitu

    SuperManitu

    Joined:
    Mar 4, 2015
    Posts:
    6
    Hi,
    one thing at the beginning, amazing plugin, it really helps a lot.
    But I think there is a Bug: When I load a project in Unity 4 some of the (array) properties aren't set any more.
    When I do this in Unity 5, some of them are deleted when I hit run, making it impossible to run my code :(
     
  24. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Hi there! Sorry to hear that. Could you elaborate? perhaps give more details? If you have a pattern to replicate the 'bug' I'd love to see it in a project folder. If not, could you post your code?
     
  25. SuperManitu

    SuperManitu

    Joined:
    Mar 4, 2015
    Posts:
    6
  26. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    How can I have a look at the struct of an element in a list?

    So I have a class called "Player" which inherits from BetterBehaviour. This class has a public struct "PlayerData" which I can see/edit in the Inspector when attached to an GameObject.
    Now I also have another class inheriting from BetterBehaviour. This one has a list List<Player>. Attaching this script to a GO and selecting a Player-Object I can't see the struct. Is that possible?
     
  27. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @SuperManitu I'm unable to replicate what you're experiencing and make the arrays lose there references. I'm adding game objects to the GUIs array, and buttons to the buttons array but they never lose their data. Are you sure it's not the editor gui flicker? Sometimes when you hit playmode your object editor disappears but if you just click anywhere on the inspector it will trigger a repaint thus appearing again. It's an inconvenient I know but it's the best I managed to get my layout system to play well with Unity's. If you still think there's a bug, you could instruct me on how to exactly replicate it, or maybe screen-record it for me?

    @BTStone Yes, by appling Inline on your list on a PerItem basis:

    Code (csharp):
    1.  
    2. public struct Data
    3. {
    4.    public readonly int id;
    5.    public readonly string name;
    6. }
    7.  
    8. public class Player : BetterBehaviour
    9. {
    10.    public Data playerData;
    11. }
    12.  
    13. public class Container : BetterBehaviour
    14. {
    15.    [PerItem, Inline]
    16.    public List<Player> players;
    17. }
    18.  

     
    BTStone likes this.
  28. SuperManitu

    SuperManitu

    Joined:
    Mar 4, 2015
    Posts:
    6
    It's defentitly not the flickering, I get Null pointer exceptions because they loose their references, Here is a gif of it:
    http://gifyu.com/images/VFW.gif

    EDIT: And these are the one which are (partly) empty at load.
     
    Last edited: Mar 8, 2015
    vexe likes this.
  29. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    So I've been working on a new extremely fast and allocation-friendly binary serializer. So far so good, I'm extremely delighted by it. Haven't done benchmarks against protobuf but I expect it to be as fast if not faster than protobuf. It emits IL to generate the serialization codes which means it won't be usable on AOT platforms unless you precompile a serialization assembly, then you'd have to stick to using only public fields/properties (I have some ideas to address those limitations) - This thing can handle pretty much anything you throw at it, but it has to know about the types upfront. I'm working on ways to make that easier. I also implemented serialization callbacks.

    Here's some (unfair, I would say) profiling against FullSerializer JSON serializer which is what we're using currently in vfw. Note how I'm reusing the memory stream, helps reduce allocation as well.



    Is that 0 bytes gc or are you just happy to see me? ;)
     
    kiriri, twobob and OnePxl like this.
  30. Jlpeebles

    Jlpeebles

    Joined:
    Oct 21, 2012
    Posts:
    54
    Thanks for adding kickass delegate like support! As far as I can tell you are not able to pass invocation args from sources (like using a variable of a target component) as you could in uAction, would this be a big deal to implement? In the mean time I will try and think if my implementation benefited from being able to do that, but upon first glance I'm not sure I can do what I am intending without that functionality.
     
  31. Jlpeebles

    Jlpeebles

    Joined:
    Oct 21, 2012
    Posts:
    54
    I braved the warning (lol) and fiddled with the uDelegate drawer.

    AlternateLayout.png

    1. I removed Invocation Args as it was already implied, and replaced that with a 4 pixel? spacing.
    2. I added a 20 pixel spacing under each entry (only if folded out though)
    3. In the arguments I added the parameter name before the type name.

    I think it's a decent bit cleaner, and assuming arguments are named in a useful manner improves workflow with multi paramter methods.

    --

    As for invocation args from sources I should be able to work around that pretty easily or do it by code.

    --

    One problem with Kickass delegates that I encountered that I also see with uDelegate is argument changes in a prefab are only saved when pressing apply, not as you edit them.
     
    Last edited: Mar 18, 2015
  32. Jlpeebles

    Jlpeebles

    Joined:
    Oct 21, 2012
    Posts:
    54
    I am having lots of serialization issues, null gameobject references on play and null handler references upon recompiling.
     
  33. SuperManitu

    SuperManitu

    Joined:
    Mar 4, 2015
    Posts:
    6
    Yeah, I got these too
     
  34. BoaNeo

    BoaNeo

    Joined:
    Feb 21, 2013
    Posts:
    56
    First of all, awesome library - so much of this should have been in the Unity core :).

    That said, I have a strange issue with a simple list of BetterBehaviours - whenever Unity re-compiles my code, I loose random elements from arrays and List<> fields. For example a list of 5 elements will consistently drop two of them. It's always the same two that are lost, even if I re-order them.

    Those same two elements might work fine in a different list, and copying the elements and referencing the copy sometimes works, sometimes not.

    I've tried deleting the list and re-creating it, no difference. I've also tried isolating the problem to a small example, but so far no luck.

    My best guess is that something in the instantiation/serialization order is messed up.

    The only fix I have right now is that if I change the base class of the script holding the array or List reference to a normal MonoBehaviour, then the problem goes away.

    (Unity 4.6.3f1, btw.)
     
  35. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Are they duplicate entries, Neo?
     
  36. wao

    wao

    Joined:
    Aug 9, 2014
    Posts:
    10
    My prefab does not hold references after applying changes.
     
  37. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Code (csharp):
    1.  
    2. Error deserializing member Properties in Sniper Shot (BaseMissile). Msg: Unable to cast <9999> (with type = System.Single) to type System.Collections.Generic.List`1[FullSerializer.fsData]. Stack:   at FullSerializer.fsData.Cast[List`1] () [0x00025] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\fsData.cs:274
    3.   at FullSerializer.fsData.get_AsList () [0x00001] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\fsData.cs:260
    4.   at FullSerializer.Internal.fsIEnumerableConverter.TryDeserialize (FullSerializer.fsData data, System.Object& instance, System.Type storageType) [0x00011] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\Converters\fsIEnumerableConverter.cs:259
    5.   at FullSerializer.fsSerializer.InternalDeserialize_4_Converter (FullSerializer.fsData data, System.Type resultType, System.Object& result) [0x0002a] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\fsSerializer.cs:681
    6.   at FullSerializer.fsSerializer.InternalDeserialize_4_Cycles (FullSerializer.fsData data, System.Type resultType, System.Object& result) [0x00047] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\fsSerializer.cs:670
    7.   at FullSerializer.fsSerializer.InternalDeserialize_3_Inheritance (FullSerializer.fsData data, System.Type storageType, System.Object& result) [0x00083] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\fsSerializer.cs:649
    8.   at FullSerializer.fsSerializer.InternalDeserialize_2_Version (FullSerializer.fsData data, System.Type storageType, System.Object& result) [0x000e6] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\fsSerializer.cs:615
    9.   at FullSerializer.fsSerializer.InternalDeserialize_1_CycleReference (FullSerializer.fsData data, System.Type storageType, System.Object& result) [0x00040] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\fsSerializer.cs:581
    10.   at FullSerializer.fsSerializer.TryDeserialize (FullSerializer.fsData data, System.Type storageType, System.Object& result) [0x0002f] in c:\Users\vexe\Desktop\MyExtensionsAndHelpers\Solution\FullSerializer\Source\fsSerializer.cs:554
    11.   at Vexe.Runtime.Serialization.BetterSerializer.Deserialize (System.Type type, System.String serializedState, System.Object context) [0x00038] in Z:\Projects\Unity\Project1\Assets\Plugins\Vexe\Runtime\Serialization\Serializers\BetterSerializer.cs:144
    12.   at Vexe.Runtime.Serialization.BetterSerializer.DeseiralizeDataIntoTarget (System.Object target, Vexe.Runtime.Serialization.SerializationData data) [0x0004d] in Z:\Projects\Unity\Project1\Assets\Plugins\Vexe\Runtime\Serialization\Serializers\BetterSerializer.cs:86
    13. UnityEngine.Debug:LogError(Object)
    14. Vexe.Runtime.Serialization.BetterSerializer:DeseiralizeDataIntoTarget(Object, SerializationData) (at Assets/Plugins/Vexe/Runtime/Serialization/Serializers/BetterSerializer.cs:92)
    15. Vexe.Runtime.Types.BetterBehaviour:Deserialize() (at Assets/Plugins/Vexe/Runtime/Types/Core/BetterBehaviour.cs:97)
    16. Vexe.Runtime.Types.BetterBehaviour:OnAfterDeserialize() (at Assets/Plugins/Vexe/Runtime/Types/Core/BetterBehaviour.cs:80)
    17. UnityEditor.DockArea:OnGUI()
    18.  
    Not sure why it's mis-casting the field, but okay... Feels like if a value is no longer needed, it shouldn't bleed over into the next field.
     
  38. kimsama

    kimsama

    Joined:
    Jan 2, 2009
    Posts:
    166
    1) Nice work! BTW, why don't you push VFW on github?
    2) Is there any plan to publish the code of dlls to be open source?

    Thanks.
     
  39. IWEF

    IWEF

    Joined:
    Jan 6, 2015
    Posts:
    3
    It seems that the order of serialization is sometimes causing the stored objects in the collection serialize before the collection and the references are nulled, that's why some of the values are serialized as null. For now I don't see how we could influence the order...
     
  40. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    VFW is causing issues where I lose serialized properties sometimes when the serializer fails. Frustrating.
     
  41. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Hey guys, sorry I haven't been responsive lately. I usually respond instantly, but I've been going through some issues. Depression, deadlocks, programmer burnouts etc. Took a whole week off doing nothing but playing chess. I'm a lonely wolf, so I asked for a programming partner in the collaboration forum, If anyone is interested check it out!

    I'll get right on the issues you guys are having. Yesterday I updated FullSerializer, there was quite a few changes. I've been trying to replicate the issues you mentioned, but I haven't been able to. I had a script with a list of BetterBehaviours in a prefab, I can't make the prefab lose the references. If anyone's interested, @Xelnath, @wao, @IWEF, @BoaNeo, @Jlpeebles PM me and I'll send you the Vfw version I have to test, see if it still has your issues, if it does, please tell me exactly how to replicate, or send me a dummy project with minimal code that reproduces the problem.

    @kimsama will do that in next release. As for the dlls source, they're just helpers/extension methods, if you're interested I might include them in an optional zip for download.

    Apologies all for the frustration.

    Btw @wao what site/software you used to create that gif?
     
  42. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    Hi Vexe. Your system very intresting for me. I think about using Full Inspector, but i found this thread... and I have two questions.
    1) uAction and uFunc work with direct assign of lambdas or only wrap them?
    2) Your system have some standart decorator, like "context menu" for example?
    P.S. Sorry for my bad English, I use them only for reading...
     
  43. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Hey andreich!

    1- Currently, you can only add methods/handlers whose target is a UnityEngine.Object (declared in a MonoBehaviour for ex) via the syntax someAciton.Add(someObj.SomeHandler); - you cannot add anonymous methods as they will not persist.
    2- Not sure exactly what you're after. Could you elaborate? are you referring to the ContextMenu Attribute?
     
  44. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Hey Vexe, you've made an awesome product here. I'm sorry to hear you're suffering through some rough times.

    How can we help?
     
  45. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    1) I understand... I have some idea... if test will be successful may I pm to you?
    2) yes, I reffering this attribute, your system have analog or, maybe, standard attribute will work fine?
     
  46. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    1) Sure go ahead.
    2) Could you write in code what you're trying to achieve? ContextMenu will work fine, as well as other attributes.
     
  47. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    Ok, if this attributes works - it's greate. I don't try your library yet, but I think it's perfect for me =)
    About delegates... you try work with IL bytes serialization (.Method.GetMethodBody().GetILAsByteArray())? I think this method slow and need some research.. but if this work, you may serialize lambdas and Action/Func without wrapping.
    P.S. I planned try save and restore delegates into file by Method.GetMethodBody().GetILAsByteArray() and MethodBuilder.CreateMethodBody... but I can only do this in a few days, not today.
     
  48. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    I haven't put any thought into it. But for starters, you can decompile Unity's dlls and see how they did it. I haven't tried it but with Unity's events you're supposed to be able to persist anonymous methods.

    Using your approach, say you got the byte array, how are you going to reconstruct the delegate using it?
     
  49. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    So... now I try work arround ILGenerator. I do not know how convert IL bytes into OpCodes, but I think this problem can be solved.
     
  50. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Has anyone successfully written a custom property drawer for a value inside of a dictionary?

    I have a dictionary of <string, MyCustomClass> and I want to render the layout when I expand so that it hides the fact that I have a wrapper class around the integer inside:

    vfw_property.png

    I would rather it draw each key/value pair like one of these:

    vfw_property_desired.png