7ark / BetterEvents-Deprecated

A replacement for UnityEvents that are: better
MIT License
135 stars 13 forks source link

SerializationAbortException: AOT serializer was missing for type 'BetterEventEntry.OdinSerializedData' when running on iOS #2

Open leoncvlt opened 5 years ago

leoncvlt commented 5 years ago

First of all: great package! Really improves the serialization of events compared to the native UnityEvents.

I have been using BetterEvents fine when developing on a PC and deploying to Android, however, when I test on iOS, my BetterEvents don't run correctly and I repeatedly get this error in the XCode log window:

No AOT serializer was pre-generated for the type 'BetterEventEntry.OdinSerializedData'. Please use Odin's AOT generation feature to generate an AOT dll before building, and ensure that 'BetterEventEntry.OdinSerializedData' is in the list of supported types after a scan. If it is not, please report an issue and add it to the list manually.
Stacktrace is not supported on this platform. 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 48)

SerializationAbortException: AOT serializer was missing for type 'BetterEventEntry.OdinSerializedData'.
  at Sirenix.Serialization.Serializer.LogAOTError (System.Type type, System.ExecutionEngineException ex) [0x00000] in <00000000000000000000000000000000>:0 
  at Sirenix.Serialization.Serializer.Create (System.Type type) [0x00000] in <00000000000000000000000000000000>:0 
  at Sirenix.Serialization.Serializer.Get (System.Type type) [0x00000] in <00000000000000000000000000000000>:0 
  at Sirenix.Serialization.Serializer.Get[T] () [0x00000] in <00000000000000000000000000000000>:0 
  at Sirenix.Serialization.SerializationUtility.DeserializeValue[T] (Sirenix.Serialization.IDataReader reader, System.Collections.Generic.List`1[T] referencedUnityObjects) [0x00000] in <00000000000000000000000000000000>:0 
  at Sirenix.Serialization.SerializationUtility.DeserializeValue[T] (System.IO.Stream stream, Sirenix.Serialization.DataFormat format, System.Collections.Generic.List`1[T] referencedUnityObjects, Sirenix.Serialization.DeserializationContext context) [0x00000] in <00000000000000000000000000000000>:0 
  at Sirenix.Serialization.SerializationUtility.DeserializeValue[T] (System.Byte[] bytes, Sirenix.Serialization.DataFormat format, System.Collections.Generic.List`1[T] referencedUnityObjects, Sirenix.Serialization.DeserializationContext context) [0x00000] in <00000000000000000000000000000000>:0 
  at BetterEventEntry.OnAfterDeserialize () [0x00000] in <00000000000000000000000000000000>:0 

I have added that entry to Odin's AOT Generation preferences, but I am still getting the issue (enabling automatic AOT generation before build or manually generating the dlls doesn't make a difference - still broken):

image

Unity version is 2019.1.4f1

leoncvlt commented 5 years ago

FYI I have opened an issue with the devs of Odin here: https://bitbucket.org/sirenix/odin-inspector/issues/558/serializationabortexception-aot-serializer

Figured out that the type to be added to the Support Serialized Types list has to follow this format: “BetterEventEntry+OdinSerializedData” - with that it seems to work.

Still trying to figure out why they're not picked up by Odin's automated scan.

PyeonggukLee commented 4 years ago

I suffer from this issue, too. It's really annoying that the type doesn't get added to the supported serialized types automatically.

kjyv commented 3 years ago

Not sure if this is a specific case when it is not found during scan but with the current version (3.0.2) of Odin, it found BetterEvents fine in my use case and added it with a + as well.

Joknaa commented 4 months ago

Did you find any solution?

robbiesaurus commented 1 month ago

I have managed to fix it myself on iOS by implementing ISerializationCallbackReceiver recursively on all classes that reference BetterEventEntry.

Here is my code as an example:

public class CutsceneManager : MonoBehaviour, ISerializationCallbackReceiver
{
    public List<CutsceneData> cutscenes;

    public void OnBeforeSerialize()
    {
        foreach (var cutscene in cutscenes)
            cutscene.OnBeforeSerialize();
    }

    public void OnAfterDeserialize()
    {
        foreach (var cutscene in cutscenes)
            cutscene.OnAfterDeserialize();
    }

    [System.Serializable]
    public class CutsceneData : ISerializationCallbackReceiver
    {
        public List<CutsceneEvent> cutsceneEvents;

        public void OnAfterDeserialize()
        {
            foreach (var cEvent in cutsceneEvents)
                cEvent.OnAfterDeserialize();
        }

        public void OnBeforeSerialize()
        {
            foreach (var cEvent in cutsceneEvents)
                cEvent.OnBeforeSerialize();
        }
    }

    [System.Serializable]
    public class CutsceneEvent : ISerializationCallbackReceiver
    {
        public BetterEventEntry cutsceneEvent;

        public void OnAfterDeserialize()
        {
            cutsceneEvent.OnAfterDeserialize();
        }

        public void OnBeforeSerialize()
        {
            cutsceneEvent.OnBeforeSerialize();
        }
    }
}

My guess is that because the MonoBehaviour was not implementing ISerializationCallbackReceiver, the internal classes were not getting picked up by Odin (just a guess...)

Hopefully this helps someone!