Baste-RainGames / SerializableAction_Unity

A faster and more flexible replacement for Unity's UnityEvent.
MIT License
43 stars 4 forks source link

Problem with Builds & IL2CPP #1

Open TeorikDeli opened 6 years ago

TeorikDeli commented 6 years ago

Hi!

First of all, GREAT plugin! Thank you! I've changed all UnityEvents and integrated your plugin to my game. It is very flexible and just perfect for my needs 🀘🏻

I'm using 2017.2 & Mac

First, I want to report you a bug which is sometimes happens and I fixed it with a workaround (I don't think it's a good one). SerializableSystemType:53 causes Errors when m_AssemblyQualifiedName is null. It happens when I select an Object in the inspector and Inspector gets refreshed continuously and I can't change anything without pressing cmd+z. I don't know why it'd be null, but I added if(m_AssemblyQualifiedName == null) m_AssemblyQualifiedName=""; just before :53 and the errors has gone. I think this happens after the first actions that I add.

My main problem is builds. I once saw an IL2CPP error, which says "... doesn't supported in IL2CPP ...", I couldn't reproduced this same error again. But, I have a reproducible problem this time.

This is my example action list:

ekran resmi 2017-12-09 21 05 08

Some methods doesn't work in the builds. Everything works fine in the editor. These are the messages: "Trying to invoke SerializableAction, but the serialized action target set_enabled has been deleted! UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[]) UnityEngine.Logger:Log(LogType, Object) UnityEngine.Debug:LogWarning(Object) SerializableActions.SerializableAction:Invoke()

c__Iterator0:MoveNext() UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) (Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)" "Trying to invoke SerializableAction, but the serialized action target set_bodyType has been deleted!" "Trying to invoke SerializableAction, but the serialized action target set_enabled has been deleted!" "Trying to invoke SerializableAction, but the serialized action target set_enabled has been deleted!" "Trying to invoke SerializableAction, but the serialized action target set_enabled has been deleted!" "Trying to invoke SerializableAction, but the serialized action target SetParent has been deleted!" "Trying to invoke SerializableAction, but the serialized action target SetParent has been deleted!" "Trying to invoke SerializableAction, but the serialized action target set_enabled has been deleted!" "Trying to invoke SerializableAction, but the serialized action target set_simulated has been deleted!" "Trying to invoke SerializableAction, but the serialized action target SetParent has been deleted!" This method invoking at the end of an IEnumerator by the way. But, I don't think that's the problem. It probably can't find Unity methods or these are not serializing while building the project. Also, my script is attached to a prefab and all referenced objects are in that prefab as child objects (as seen in the screenshot). Do you have any suggestions to fix that, or anything you want me to try?
Baste-RainGames commented 6 years ago

Hi!

Thanks for the warm words! The bug in SerializableSystemType should be pretty easy to fix robustly. Do you have anything specific that triggers it? That'll help a lot.

For the IL2CPP stuff, I'm not sure, but I've got a suspicion. IL2CPP translates the code to c++ (as the method suggests), and it might be that the names of methods are changed such that they can't be created through reflection. To check that, you could compare the names of a serialized method between builds and the editor. On the target platform, try to make a SerializableAction_Single at runtime for the target methods, and print Target.TargetMethod.MethodName, and compare that to the value that you get in the editor. If that's the case, then we'll have to check if there's some way to work around that.

It also might be something entirely different. What are you building for? There are some target platforms (like IOS) where I know that parts of reflection are not available due to restrictions from the platform holder. It could be that some Fasterflect internals are tripping them up. To check that, try to use Fasterflect to generate a method and call it without going through SerializableAction at all. If that fails, then method serialization has to be implemented differently for that platform.

Finally, if you're targeting a platform that does code stripping, it could be that the methods are just removed as they're not found in any of your compiled code, so they're not available at runtime. I would usually suspect that, but you're using things like Component.enabled, which I really doubt that you never call anywhere else! But just in case, if stripping's involved on the platform, try turning it off.

TeorikDeli commented 6 years ago

I'm creating a new test scene. My target platform is iOS.

While making the new actions, I reproduced the first bug that I mentioned. Console log:

"ArgumentNullException: Argument cannot be null. Parameter name: TypeName System.Type.GetType (System.String typeName) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Type.cs:454) SerializableActions.Internal.SerializableSystemType.GetSystemType () (at Assets/Plugins/SerializableAction/Scripts/SerializableSystemType.cs:54) SerializableActions.Internal.SerializableSystemType.get_SystemType () (at Assets/Plugins/SerializableAction/Scripts/SerializableSystemType.cs:45) SerializableActions.Internal.SerializableSystemType.Equals (SerializableActions.Internal.SerializableSystemType _Object) (at Assets/Plugins/SerializableAction/Scripts/SerializableSystemType.cs:81) SerializableActions.Internal.SerializableSystemType.Equals (System.Object obj) (at Assets/Plugins/SerializableAction/Scripts/SerializableSystemType.cs:74) System.Object.Equals (System.Object objA, System.Object objB) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Object.cs:70) SerializableActions.Internal.SerializableFieldSetter.Equals (SerializableActions.Internal.SerializableFieldSetter other) (at Assets/Plugins/SerializableAction/Scripts/SerializableFieldSetter.cs:29) SerializableActions.Internal.SerializableFieldSetter.Equals (System.Object obj) (at Assets/Plugins/SerializableAction/Scripts/SerializableFieldSetter.cs:39) System.Collections.Generic.EqualityComparer1+DefaultComparer[SerializableActions.Internal.SerializableFieldSetter].Equals (SerializableActions.Internal.SerializableFieldSetter x, SerializableActions.Internal.SerializableFieldSetter y) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/EqualityComparer.cs:84) System.Array.IndexOf[SerializableFieldSetter] (SerializableActions.Internal.SerializableFieldSetter[] array, SerializableActions.Internal.SerializableFieldSetter value, Int32 startIndex, Int32 count) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Array.cs:2133) System.Collections.Generic.List1[SerializableActions.Internal.SerializableFieldSetter].IndexOf (SerializableActions.Internal.SerializableFieldSetter item) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:379) SerializableActions.Internal.SerializableAction_SingleDrawer.DrawSerializableAction (Rect position, UnityEditor.SerializedProperty property) (at Assets/Plugins/SerializableAction/Scripts/Editor/SerializableAction_SingleDrawer.cs:157) SerializableActions.Internal.SerializableActionDrawer+cAnonStorey0.<>m1 (Rect rect, Int32 index, Boolean active, Boolean focused) (at Assets/Plugins/SerializableAction/Scripts/Editor/SerializableActionDrawer.cs:48) UnityEditorInternal.ReorderableList.DoListElements (Rect listRect) (at /Users/builduser/buildslave/unity/build/Editor/Mono/GUI/ReorderableList.cs:582) UnityEditorInternal.ReorderableList.DoList (Rect rect) (at /Users/builduser/buildslave/unity/build/Editor/Mono/GUI/ReorderableList.cs:407) SerializableActions.Internal.SerializableActionDrawer.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at Assets/Plugins/SerializableAction/Scripts/Editor/SerializableActionDrawer.cs:32) UnityEditor.PropertyDrawer.OnGUISafe (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at /Users/builduser/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyDrawer.cs:22) UnityEditor.PropertyHandler.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) (at /Users/builduser/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:142) UnityEditor.EditorGUI.PropertyFieldInternal (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) (at /Users/builduser/buildslave/unity/build/Editor/Mono/EditorGUI.cs:5568) UnityEditor.EditorGUI.PropertyField (Rect position, UnityEditor.SerializedProperty property, Boolean includeChildren) (at /Users/builduser/buildslave/unity/build/artifacts/generated/common/editor/EditorGUIBindings.gen.cs:1040) UnityEditor.EditorGUI.PropertyField (Rect position, UnityEditor.SerializedProperty property) (at /Users/builduser/buildslave/unity/build/artifacts/generated/common/editor/EditorGUIBindings.gen.cs:1035) UnityEditor.Editor.OptimizedInspectorGUIImplementation (Rect contentRect) (at /Users/builduser/buildslave/unity/build/artifacts/generated/common/editor/EditorBindings.gen.cs:279) UnityEditor.GenericInspector.OnOptimizedInspectorGUI (Rect contentRect) (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/GenericInspector.cs:32) UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor[] editors, Int32 editorIndex, Boolean rebuildOptimizedGUIBlock, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect) (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1220) UnityEditor.InspectorWindow.DrawEditors (UnityEditor.Editor[] editors) (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1021) UnityEditor.InspectorWindow.OnGUI () (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:362) System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222) Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation. System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232) System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MethodBase.cs:115) UnityEditor.HostView.Invoke (System.String methodName, System.Object obj) (at /Users/builduser/buildslave/unity/build/Editor/Mono/HostView.cs:285) UnityEditor.HostView.Invoke (System.String methodName) (at /Users/builduser/buildslave/unity/build/Editor/Mono/HostView.cs:278) UnityEditor.HostView.InvokeOnGUI (Rect onGUIPosition) (at /Users/builduser/buildslave/unity/build/Editor/Mono/HostView.cs:245)"

I created a new script. Added it to a gameobject, then added + to add new action, then dragged an UI button to it, then console gave me this message. Also, inspector became empty:

ekran resmi 2017-12-10 00 02 39

Then cmd+z and cmd+shift+z to undo & redo:

ekran resmi 2017-12-10 00 03 57

I hope this helps. I'll write again after I test the test scene. Thanks! 🀘🏻

Baste-RainGames commented 6 years ago

Hi!

So I fixed that bug! Back in April! Turns out I just never remembered to push the commit to github. It's essentially the null-check you suggested.

I also did some minor cleanups to the code, and pushed it. So the fix is availalbe. I should probably go through the code and figure out why the assembly qualified name gets set to null if you assign eg. a UnityEngine.UI.Button, though.

I'll see if I can get time to check out what's going on with IL2CPP. That'll be harder to figure out. If you can figure out some more about that bug, I'd love to hear it!

TeorikDeli commented 6 years ago

Well, thanks! As I tried, I can't get anything to work on iOS =/

I created this script in my test:

"using SerializableActions; using UnityEngine;

public class testScript : MonoBehaviour {

[SerializeField]
SerializableAction action;
[SerializeField]
SerializableAction action2;

// Use this for initialization
void Start() {
    Hello("a");
    GetComponent<Collider>().enabled = false;
    action.Invoke();
    action2.Invoke();

}

// Update is called once per frame
void Update() {

}

public void Hello(string m) {
    Debug.Log("my message from this action: " + m);
}

}"

Output: "my message from this action: a Trying to invoke SerializableAction, but the serialized action target set_enabled has been deleted! Trying to invoke SerializableAction, but the serialized action target Hello has been deleted!"

Unfortunately, Invokes doesn't work at all on the device (both 32bit & 64bit). =( I also tried without strip.

I believe Fasterflect just doesn't compatible with the iOS. But, I really don't know much about Fasterflect or Reflections in C#. As I understand, serializing & deserializing are working. If I figure out anything, I'll write!

I also found a plugin which is using Fastreflect (https://assetstore.unity.com/packages/tools/ufaction-17817). I'll test it when I find some time asap.