0
Fixed

iOS AOT Prebuild missing custom script functions

petergtruong 2 years ago updated by Lazlo Bonin (Lead Developer) 2 years ago 11

Using MacOS High Sierra and Unity 2017.2 p3. I have a custom script that spawns items and alters camera effects through other script references. My gameobject has both the flow machine and this custom script and the flow machine uses these functions in question. After a player presses start, a script turns this gameobject on which should activate the script and the flow machine and everything works fine, but when I prebuild and build through Xcode, I get ExecutionEngineException errors. Note that the editor works completely fine and it's only once I do an iOS build everything no longer works. I get multiple errors like the one below. Any help would be appreciated.


Error:

ExecutionEngineException: Attempting to call method ‘Ludiq.InstanceFunctionInvoker`6[[NewSpawnerHelper, Assembly-CSharp, Version=0.0.0.0, Culture=, PublicKeyToken=null],[System.Single, mscorlib, Version=2.0.0.0, Culture=, PublicKeyToken=b77a5c561934e089],[System.Single, mscorlib, Version=2.0.0.0, Culture=, PublicKeyToken=b77a5c561934e089],[System.Single, mscorlib, Version=2.0.0.0, Culture=, PublicKeyToken=b77a5c561934e089],[System.Single, mscorlib, Version=2.0.0.0, Culture=, PublicKeyToken=b77a5c561934e089],[System.Single, mscorlib, Version=2.0.0.0, Culture=, PublicKeyToken=b77a5c561934e089]]::.ctor’ for which no ahead of time (AOT) code was generated.
  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at Ludiq.OptimizedReflection.GetMethodInvoker (System.Reflection.MethodInfo methodInfo) [0x00000] in <filename unknown>:0 
  at Ludiq.Member.Prewarm () [0x00000] in <filename unknown>:0 
  at Ludiq.Graph.Prewarm () [0x00000] in <filename unknown>:0 
  at Ludiq.GraphNest`2[TGraph,TMacro].Instantiate (System.Collections.Generic.Dictionary`2 parentInstantiations) [0x00000] in <filename unknown>:0 
  at Ludiq.GraphNest`2[TGraph,TMacro].Instantiate () [0x00000] in <filename unknown>:0 
  at Bolt.FlowMachine.Awake () [0x00000] in <filename unknown>:0 
  at CountdownTimer+<timer>c__Iterator0.MoveNext () [0x00000] in <filename unknown>:0 
  at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) [0x00000] in <filename unknown>:0 
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at Ludiq.OptimizedReflection.GetMethodInvoker (System.Reflection.MethodInfo methodInfo) [0x00000] in <filename unknown>:0 
  at Ludiq.Member.Prewarm () [0x00000] in <filename unknown>:0 
  at Ludiq.Graph.Prewarm () [0x00000] in <filename unknown>:0 
  at Ludiq.GraphNest`2[TGraph,TMacro].Instantiate (System.Collections.Generic.Dictionary`2 parentInstantiations) [0x00000] in <filename unknown>:0 
  at Ludiq.GraphNest`2[TGraph,TMacro].Instantiate () [0x00000] in <filename unknown>:0 
  at Bolt.FlowMachine.Awake () [0x00000] in <filename unknown>:0 
  at CountdownTimer+<timer>c__Iterator0.MoveNext () [0x00000] in <filename unknown>:0 
  at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) [0x00000] in <filename unknown>:0 
<timer>c__Iterator0:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
 
(Filename: currently not available on il2cpp Line: -1)
Bolt Version:
Unity Version:
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):

Take a look here if you have not, https://support.ludiq.io/forums/4-bolt-manual/topics/161-building-for-aot-platforms/

Also do a search of AOT on the forums and Discord. There are several threads and discussions that might help until Lazlo has a chance to respond. 

Thanks William, but unfortunately my friend and I have been tearing our hairs apart trying to figure this out and we've went through the forum and discord in hopes to find something but nothing has worked so far. We'll continue searching for a solution though.

Well, please stop pulling your hair out before you both go bald, ha. Seriously though, I do not build for mobile so can offer no solid solution, and even though Lazlo is under the weather  he seems to still  be watching the forums and will probably provide an answer tomorrow. Maybe move on to something else till then.

Pending Review

Hi Peter,

Can you paste the definition for the function on NewSpawnerHelper that takes 5 float arguments?

Also, after having run AOT pre-build, can you check in Assets/Generated/Ludiq.Core/AotStubs.cs if there is a matching stub for this method?

Hey Lazlo,

Thank you for the response, my friend and I found out that we had to have the gameObjects with the flow machines active at the start. If they were turned on later in the scene, they would throw errors in our build. 

If it helps though, here is the function:

public void SpawnItem(Transform obj, float forward, float up, float right, int index, bool onFloor = true){
Vector3 finalPos; if (onFloor){ finalPos = this.SetVectorY(obj.position + (obj.forward*forward) + (obj.right*right) + (obj.up*up), yValue);
GameObject spawned = Instantiate(this.objToSpawn[index], finalPos, objToSpawn[index].transform.rotation); spawned.transform.position += this.GrabBoundsY(spawned.transform); } else {
GameObject spawned = Instantiate(this.objToSpawn[index], finalPos, objToSpawn[index].transform.rotation); } }

and also the AOTStubs did have this function as SpawnItem.

Hm, that might be the cause of the bug then. Did the AotStubs.cs have this function when you disabled your game object before start?

I'm thinking that AOT pre-build might skip inactive objects when looking for stubs to create.

(PS: Please use code formatting! First button in the toolbar)

Ooo sorry about the code formatting! And also AotStubs did have the function but it still broke.

Are you absolutely certain? It seems unlikely to me. These ExecutionEngineExceptions so far only happened when the AotStubs.cs did not contain the proper method. Can you test again (disable the game objects, run AOT pre-build and check if the stubs are there?).

Otherwise I don't know what might have caused your bug and can't fix it.

Alright, so I tried pre-building then building with the game objects off, it seems to miss some functions within my script once I turn them on thus giving me the ExecutionEngineExceptions. When I pre-build and then build when the game objects are active at the start, everything is put into the AotStubs.cs like normal. Hopefully that helps!