Using RemObjects SDK from within Unity Game Engine

We’re trying to use RemObjects SDK to make calls from within a Unity Game Engine environment (Mono) back into a Delphi (XE2) application.

Simple .Net client code compiles fine in Unity but immediately times out as soon as the first RemObject SDK service method is called.

The RemObjects server application doesn’t even appear to receive a connection attempt.

Does anyone have any experience or ideas about getting RemObjects SDK working with Unity.

Struan

Further information:

We got the RemObjects SDK Client working from within the Unity Game Engine editor by throwing more assemblies in the Unity loader path.

But now when we try to build a Unity Web player of the scene, it complains that Windows.Form (or a assembly required by Windows.Form) is not permitted in the Unity Web Player.

I know it’s not a simple task, but is there any plans to to have a core RemObjects SDK assembly that does not require any UI assemblies.

Hmm. That’s a good point, yes. System.Windows.Forms is so deeply part of the core framework, that we never considered it not being available to be a concern. We should look into that. In the mean time, we just added a portable Class Library version of the libraries. This will be in the next release, and it’s also in the current beta we shipped yesterday. Do you feel like testing if that PCL version will work with Unity?

Hey guys,

I know that this is really an old one, but I am going the same way now (RO / DA in Unity) and have several issues. So I am collecting as much information as possible. I guess thath things have become a bit more difficult with this approach since you have to use Unity’s IL to C++ compiler to have a new 64bit app that will be approved for the app store. The RO .NET SDK dlls seem to compile fine while the DA dlls throw errors (Jsondatastreamer), so I am looking for options and experiences.

Hello

Could you post the errors you got?
Also could you ping the Unity3D support regarding the fact that their tool produces a non-compilable code?

Regards

Hi Anton,

thanks for your reply. I will try to give an overview of my problem, as short as possible.

Unity uses its own Mono VM to execute your C# scripts to control the game behavior. Their Mono version is labeled “2.0” and should cover .NET 3.5 pretty well. This way Unity supports many platforms. For the moment, I am targeting only iOS.

Unity provides several options to include external functionality:

  1. drop the compiled .NET dlls (mono compatible, <= .NET 3.5) somewhere in the Unity project and reference / use their classes in your C# code

  2. drop your classes’ source code (written in Objective-C or C) in your Xcode project so it gets compiled into your project. Use a C# wrapper to access them

  3. include compiled native libraries (static .a for iOS) in your Unity project and reference / use them by a special [DllImport] (and C# wrapper if necessary).

In the project I am currently working on, I wanted to use DA’s briefcases for local data storage and sync them with a remote DA server. I played with option 3) and it seems to work as far as I can tell. Unfortunately I don’t know much (yet) about developing native IOS libraries. Still I was able to write and compile a very basic one (a function returning an integer) using Oxygene and use it in the game. But of course option 1) is the preferable one. Option 2) means learning another language - maybe later, after I finished this project :wink:

There is a particularity for iOS projects: To have new apps approved on the Apple app store, it must be a 64 bit app. This is accomplished in Unity by a new IL to C++ compiler that can produce the 64 bit binaries. So basically the C# scripts and dropped .NET dlls get compiled by the Mono compiler, the resulting IL output gets compiled to C++ code by IL2CPP, then the project gets compiled for iOS in Xcode. Unity injects a IL2CPP runtime library into the executable to support the virtual machine. This workflow is very new and new bugs are found, of course. So in many cases it is not clear if a .NET dll is not compatible or if there is a bug in the IL2CPP compiler.

In the case of the DA dll I found the following compiler output:

> Warning:
> ---------
> System.Windows.Forms.dll assembly is referenced by user code, but is not supported on iOS platform. Various failures might follow.
> UnityEditor.HostView:OnGUI()

> Error:
> --------
> Failed running C:\Program Files\Unity 5.0.2p4\Editor\Data\il2cpp/build/il2cpp.exe --copy-level=None --emit-null-checks --enable-array-bounds-check --enable-symbol-loading --development-mode --development-mode --extra-types.file="C:\Program Files\Unity 5.0.2p4\Editor\Data\il2cpp\il2cpp_default_extra_types.txt" --assembly="L:\BF Projects\J\Temp\StagingArea\Data\Managed\Assembly-CSharp-firstpass.dll" --assembly="L:\BF Projects\J\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll" --assembly="L:\BF Projects\J\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll" --assembly="L:\BF Projects\J\Temp\StagingArea\Data\Managed\RemObjects.DataAbstract.dll" --assembly="L:\BF Projects\J\Temp\StagingArea\Data\Managed\RemObjects.SDK.dll" --assembly="L:\BF Projects\J\Temp\StagingArea\Data\Managed\RemObjects.InternetPack.dll" --assembly="L:\BF Projects\J\Temp\StagingArea\Data\Managed\RemObjects.SDK.ZLib.dll" --generatedcppdir="L:\BF Projects\J\Temp\il2cppOutput\il2cppOutput" --builder=none

> stdout:

> IL2CPP error for type 'RemObjects.DataAbstract.JsonDataStreamer/JsonDataReader' in assembly 'L:\BF Projects\J\Temp\StagingArea\Data\Managed\RemObjects.DataAbstract.dll'
> Additional information: Build a development build for more information. Exception has been thrown by the target of an invocation.
> il2cpp.exe didn't catch exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NotSupportedException: Operation is not supported.
>   at Unity.IL2CPP.Extensions.ContainsGenericParameters (Mono.Cecil.TypeReference typeReference) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeVisitor.ProcessTypeReference (Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.TypeDefinitionVisitor.Visit (Mono.Cecil.FieldDefinition fieldDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Visitor.Visit (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.TypeDefinitionVisitor.Visit (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
>   --- End of inner exception stack trace ---
>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
>   at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Visitor.Visit[TypeDefinition] (Mono.Cecil.TypeDefinition node, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Extensions.DoAccept[TypeDefinition] (Mono.Cecil.TypeDefinition definition, Unity.Cecil.Visitor.Visitor visitor) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Extensions.Accept (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Visitor visitor) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeCollector.ForTypeDefinition (Mono.Cecil.TypeDefinition type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeCollector.ForTypeDefinition (Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeWriter.WriteTypeDefinitionIncludes (Mono.Cecil.TypeReference type, Unity.IL2CPP.CppCodeWriter writer) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.SourceWriter.WriteTypeDefinitionFor (NiceIO.NPath outputDirectory, Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.SourceWriter.Write (Mono.Cecil.AssemblyDefinition assemblyDefinition, Unity.IL2CPP.GenericsCollection.InflatedCollection allGenerics, NiceIO.NPath outputDir, Mono.Cecil.TypeDefinition[] typeList, Unity.IL2CPP.StringLiterals.StringLiteralCollection stringLiteralCollection) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.Convert (Mono.Cecil.AssemblyDefinition assemblyDefinition, Unity.IL2CPP.StringLiterals.StringLiteralCollection stringLiteralCollection, Unity.IL2CPP.GenericsCollection.InflatedCollection allGenerics) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.Apply () [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.ConvertAssemblies (System.String[] assemblies, NiceIO.NPath outputDir, System.Collections.Generic.List`1 additionalCpp) [0x00000] in <filename unknown>:0
> stderr:

> Unhandled Exception:
> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NotSupportedException: Operation is not supported.
>   at Unity.IL2CPP.Extensions.ContainsGenericParameters (Mono.Cecil.TypeReference typeReference) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeVisitor.ProcessTypeReference (Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.TypeDefinitionVisitor.Visit (Mono.Cecil.FieldDefinition fieldDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Visitor.Visit (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.TypeDefinitionVisitor.Visit (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0

>   --- End of inner exception stack trace ---

>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
>   at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Visitor.Visit[TypeDefinition] (Mono.Cecil.TypeDefinition node, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Extensions.DoAccept[TypeDefinition] (Mono.Cecil.TypeDefinition definition, Unity.Cecil.Visitor.Visitor visitor) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Extensions.Accept (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Visitor visitor) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeCollector.ForTypeDefinition (Mono.Cecil.TypeDefinition type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeCollector.ForTypeDefinition (Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeWriter.WriteTypeDefinitionIncludes (Mono.Cecil.TypeReference type, Unity.IL2CPP.CppCodeWriter writer) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.SourceWriter.WriteTypeDefinitionFor (NiceIO.NPath outputDirectory, Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.SourceWriter.Write (Mono.Cecil.AssemblyDefinition assemblyDefinition, Unity.IL2CPP.GenericsCollection.InflatedCollection allGenerics, NiceIO.NPath outputDir, Mono.Cecil.TypeDefinition[] typeList, Unity.IL2CPP.StringLiterals.StringLiteralCollection stringLiteralCollection) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.Convert (Mono.Cecil.AssemblyDefinition assemblyDefinition, Unity.IL2CPP.StringLiterals.StringLiteralCollection stringLiteralCollection, Unity.IL2CPP.GenericsCollection.InflatedCollection allGenerics) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.Apply () [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.ConvertAssemblies (System.String[] assemblies, NiceIO.NPath outputDir, System.Collections.Generic.List`1 additionalCpp) [0x00000] in <filename unknown>:0
> [ERROR] FATAL UNHANDLED EXCEPTION: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NotSupportedException: Operation is not supported.
>   at Unity.IL2CPP.Extensions.ContainsGenericParameters (Mono.Cecil.TypeReference typeReference) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeVisitor.ProcessTypeReference (Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.TypeDefinitionVisitor.Visit (Mono.Cecil.FieldDefinition fieldDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Visitor.Visit (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.TypeDefinitionVisitor.Visit (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0

>   --- End of inner exception stack trace ---

>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
>   at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Visitor.Visit[TypeDefinition] (Mono.Cecil.TypeDefinition node, Unity.Cecil.Visitor.Context context) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Extensions.DoAccept[TypeDefinition] (Mono.Cecil.TypeDefinition definition, Unity.Cecil.Visitor.Visitor visitor) [0x00000] in <filename unknown>:0
>   at Unity.Cecil.Visitor.Extensions.Accept (Mono.Cecil.TypeDefinition typeDefinition, Unity.Cecil.Visitor.Visitor visitor) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeCollector.ForTypeDefinition (Mono.Cecil.TypeDefinition type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeCollection.NonTemplated.IncludeCollector.ForTypeDefinition (Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.IncludeWriter.WriteTypeDefinitionIncludes (Mono.Cecil.TypeReference type, Unity.IL2CPP.CppCodeWriter writer) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.SourceWriter.WriteTypeDefinitionFor (NiceIO.NPath outputDirectory, Mono.Cecil.TypeReference type) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.SourceWriter.Write (Mono.Cecil.AssemblyDefinition assemblyDefinition, Unity.IL2CPP.GenericsCollection.InflatedCollection allGenerics, NiceIO.NPath outputDir, Mono.Cecil.TypeDefinition[] typeList, Unity.IL2CPP.StringLiterals.StringLiteralCollection stringLiteralCollection) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.Convert (Mono.Cecil.AssemblyDefinition assemblyDefinition, Unity.IL2CPP.StringLiterals.StringLiteralCollection stringLiteralCollection, Unity.IL2CPP.GenericsCollection.InflatedCollection allGenerics) [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.Apply () [0x00000] in <filename unknown>:0
>   at Unity.IL2CPP.AssemblyConverter.ConvertAssemblies (System.String[] assemblies, NiceIO.NPath outputDir, System.Collections.Generic.List`1 additionalCpp) [0x00000] in <filename unknown>:0

> UnityEngine.Debug:LogError(Object)
> UnityEditorInternal.Runner:RunManagedProgram(String, String, String, CompilerOutputParserBase) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:66)
> UnityEditorInternal.IL2CPPBuilder:ConvertPlayerDlltoCpp(ICollection`1, String, String) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:436)
> UnityEditorInternal.IL2CPPBuilder:Run() (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:281)
> UnityEditorInternal.IL2CPPUtils:RunIl2Cpp(String, String, IIl2CppPlatformProvider, Action`1, RuntimeClassRegistry) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:211)
> UnityEditor.HostView:OnGUI()

So that’s a lot of text, but perhaps the first line says it all - the use of Windows.Forms in DA ? If this is the case, I simply can’t use it as described in Option 1). Furthermore, I saw somewhere that the DA .NET dlls refernce .NET 4.0 which means that it will not work.
If it is a compiler bug in IL2CPP, I could post it as a Unity bug and hope that it gets fixed and that not too many new bugs will appear, but it is too new to be perfect, especially in more complicated projects/scenarios. As mentioned earlier, due to the project schedule 2) is not an option at the moment. But I also would like to avoid option 3) because it is also very time consuming in comparison to option 1).

Currently I am thinking if I should use local SQLite instead of DA (there are mono dlls for SQlite that work in Unity/iOS) and create my own transport using RO SDK because it seems to work out of the box.

I was also hoping that several DA users have some experience with RO / DA in this pretty complex Unity architecure / workflow.


EDIT:
I just saw that the RO SDK (without DA) also produces the warning

System.Windows.Forms.dll assembly is referenced by user code, but is not supported on iOS platform. Various failures might follow.
UnityEditor.HostView:OnGUI()

but no errors following. Not sure if it will build in Xode or run on iOS later though.


EDIT 2:
no it doesn’t :-\

Hello

Thank you for clarification of the build process. Does Unity3d accept Portable Class Library assemblies? That would greatly help.

Hi Anton,

unfortunately not. There was a request back in late 2013, but it never received enough votes from the community (which is a bit strange, because Unity’s biggest advantage over other game engines is definitely the number of supported platforms). But I guess this would require Mono 3.0 anyway, so no chance.

Thanks for your time and advice. I was looking forward to use DA here, hoping that I can use it with Unity’s mono. Playing with simple Oxygene static iOS libraries was fun and easy. But my knowledge about native iOS programming is still too limited for this project. I will and want to learn, but for now I think I will play with local SQLite and the built-in WWW class and dive into real native iOS programming later when/if there is some spare time.

Hello

There could be one more issue with the Data Abstract (but not with the SDK).This conversion most probably breaks the DA licensing stuff, so its components won’t be accessible anyway.

Still please drop a mail to support@ and we’ll try to find some solution.

Regards