Forum Xamarin.Forms

iOS Binding Unity as a library

GraverobberGraverobber Member ✭✭✭

Hi all,

I don't even know where to start :D

Since alpha 2019.3 Unity offers the feature "Unity as a Library" https://blogs.unity3d.com/2019/06/17/add-features-powered-by-unity-to-native-mobile-apps/ which I'm currently trying to integrate into one of our Xamarin Apps.
There are descriptions how to do that natively for Android and iOS which I got both working fine.
Just for reference:
https://forum.unity.com/threads/integration-unity-as-a-library-in-native-ios-app.685219/
https://forum.unity.com/threads/integration-unity-as-a-library-in-native-android-app.685240/
This is actually a really big deal so it is great working on it :D

However, I got it working fine for Xamarin Android. Now I'm trying on iOS which appears to be much more complicated.

The unity project will be exported as a native Objective-C++ framework (I think at least as there are .mm files using Objective C)
When using Sharpie to bind the framework I get a super large APIDefinitions file.
After some research I figured out that I have to define a scope to the Headers of the Framework, then the APIDefinitions are in fact much smaller and only reference the header files.

Now to my (current) problem:

If I open the ApiDefinitions then there is an interface UnityFramewok which comes from the UnityFramework.h file.
But this header holds a reference to a class UnityView which is not part of the headers. It is within the framework( at least it is within the Library project in Xcode so I assume it is bundled into the framework.)
I copied the .framework into the bindings Native References but I can't see any actual change happening when I do that.
The UnityView can not be found within the interface and I also can't import it from the library because the native reference is not available.

So how can I reference to a class of the framework from within an interface that is defined in the ApiDefinitions?

Thank you already!

Best Answer

  • GraverobberGraverobber Member ✭✭✭
    Accepted Answer

    So I solved it all by my own now :)
    I manually adjusted the generated Library code to avoid the need of complicated APIDefinitions. Then I just bound one class and used the methods I added in order to have everything working.

    Thank you.

«1

Answers

  • GraverobberGraverobber Member ✭✭✭
    edited July 2019

    So little update on what else I tried so far:

    I found this https://docs.microsoft.com/en-us/xamarin/cross-platform/macios/native-references
    so not sure what exactly it means for me. But if I understand correctly it means I don't even need a Binding project.
    So I tried adding the framework to the native references, I build the project for my iPad (as the lib only support arm64 so I can not build for Simulator) and it builds fine. But then I can not use the framework in my code, it is the same as with the binding it is just not found. (for example writing using UnityFramework; in my AppDelegate will cause an error saying UnityFramework can't be found are you missing an using....)

    I changed the framework to a static library .a file and tried with that. But here I get 4 errors when building saying:

    .iOS/clang: Error: linker command failed with exit code 1 (use -v to see invocation) (MyApp.iOS)
    .iOS/error MT5209: Error: library not found for -lUnityFramework (MyApp.iOS) Native linking
    .iOS/MTOUCH: Error MT5201: Native linking failed. Please review the build log and the user flags provided to gcc: -ObjC -LLibraries -lUnityFramework (MT5201) (MyApp.iOS)
    .iOS/MTOUCH: Error MT5202: Native linking failed. Please review the build log. (MT5202) (MyApp.iOS)

    Unfortunately I don't know where to find the Build log in order to review it.
    Does anyone know how I can solve these errors?

  • GraverobberGraverobber Member ✭✭✭
    edited July 2019

    Okay I have the feeling I'm almost there!
    I rolled back to using an iOS Binding project. I decided to just bind the one class that I'm using natively and the few methods and ignore anything else and that seems to work fine.
    I also added a few methods to the library in order to make my life easier and just call simple binding methods from Xamarin.

    However, there is one method I have to use which gives me an native exception when calling which is:

    - (void)runEmbeddedWithArgc:(int)argc argv:(char*[])argv appLaunchOpts:(NSDictionary*)appLaunchOpts
    

    My guess is that something is wrong with char*[]argv. Here is how I defined it in APIDefinitios.cs

    //- (void)runEmbeddedWithArgc:(int)argc argv:(char*[])argv appLaunchOpts:(NSDictionary*)appLaunchOpts
    [Export("runEmbeddedWithArgc:argv:appLaunchOpts:")]
    void RunEmbeddedWithArgc(int argc, string[] argv, NSDictionary options);
    

    Important to note, argv is what the app has when it start and the static main function is called.

    int main(int argc, char * argv[]) {
        @autoreleasepool {
            args = argv;
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    

    When I call it like this
    ufw.RunEmbeddedWithArgc(1, Application.originalArgs, originalOptions);

    the app crashes (originalOptions is just an empty Dictionary because the one passed to Finishedlaunching is null and null is not allowed in runEmbeddedWithArgc)

    The stack trace is

    =================================================================

    Native Crash Reporting

    Got a SIGSEGV while executing native code. This usually indicates
    a fatal error in the mono runtime or one of the native libraries

    used by your application.

    =================================================================

    Basic Fault Adddress Reporting

    Memory around native instruction pointer (0x106711b74):0x106711b64 00 00 80 d2 c0 03 5f d6 e0 03 08 aa c0 03 5f d6 ..............
    0x106711b74 08 00 c0 39 09 05 01 51 0a 81 00 11 3f 69 00 71 ...9...Q....?i.q
    0x106711b84 48 31 88 1a 29 00 c0 39 2a 05 01 51 2b 81 00 11 H1..)..9*..Q+...
    0x106711b94 5f 69 00 71 6a 31 89 1a 09 1d 00 12 69 02 00 34 _i.qj1......i..4

    =================================================================

    Native stacktrace:

    0x104e8d308 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x104e833f0 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x104e91c58 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : mono_pmip
    0x2194b19f0 - /usr/lib/system/libsystem_platform.dylib :
    0x1067466a4 - /private/var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/Frameworks/UnityFramework.framework/UnityFramework : _ZdaPvRKSt9nothrow_t
    0x106745fc0 - /private/var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/Frameworks/UnityFramework.framework/UnityFramework : _ZdaPvRKSt9nothrow_t
    0x106b2e8dc - /private/var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/Frameworks/UnityFramework.framework/UnityFramework : _ZN9MetalHeap14AliasResourcesEv
    0x105d68d90 - /private/var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/Frameworks/UnityFramework.framework/UnityFramework : UnityAdsEngineSetDidFinishCallback
    0x105d68f74 - /private/var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/Frameworks/UnityFramework.framework/UnityFramework : UnityAdsEngineSetDidFinishCallback
    0x104dcaeb0 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x104dc99b8 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x102c0bea0 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x102c0bcfc - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x102f6ebe8 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x104e95104 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : mono_pmip
    0x104f3856c - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : mono_pmip
    0x104f3be80 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : mono_pmip
    0x102bd58f4 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x102bd60ec - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x2464b99f0 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    Thread started: #9
    0x2464bb158 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x2464c0ba4 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d5c948 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d655c8 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d5c5c4 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d5cf64 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d5b064 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d5ad10 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d5fed0 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d60e30 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : _performActionsWithDelayForTransitionContext
    0x245d5fd88 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x245d64c74 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    2019-07-17 17:14:54.757 MyApp.iOS[3270:1862901] True
    0x2464bf09c - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x2460aa250 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore :
    0x21c2db9d4 - /System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices :
    0x21c2e679c - /System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices :
    0x21c2e5e94 - /System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices :
    0x2192de484 - /usr/lib/system/libdispatch.dylib :
    0x219281e10 - /usr/lib/system/libdispatch.dylib :
    0x21c31aa9c - /System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices :
    0x21c31a728 - /System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices :
    0x21c31ad44 - /System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices :
    0x2198351f0 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation :
    0x219835170 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation :
    0x219834a54 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation :
    0x21982f920 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation :
    0x21982f1f0 - /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation : CFRunLoopRunSpecific
    0x21baa8584 - /System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices : GSEventRunModal
    0x2464c2950 - /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore : UIApplicationMain
    0x1039c9564 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x103926a3c - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x1039269c4 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x102c0b9cc - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x102f6ebe8 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x104e95104 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : mono_pmip
    0x104f3856c - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : mono_pmip
    0x104f3e76c - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : mono_pmip
    0x104e73a34 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x10503173c - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : _Z9__isctypeim
    0x102c0b8a0 - /var/containers/Bundle/Application/C8CF6969-5933-4E55-9C09-ACF6CD2346E9/MyApp.iOS.app/MyApp.iOS : (null)
    0x2192eebb4 - /usr/lib/system/libdyld.dylib :

    =================================================================

    Managed Stacktrace:

    at <0xffffffff>
    at ApiDefinition.Messaging:void_objc_msgSend_int_IntPtr_IntPtr <0x00007>
    at UnityFrameworkBinding.UnityFramework:RunEmbeddedWithArgc <0x00287>
    at MyApp.iOS.AppDelegate:LoadUnity <0x000ff>
    at MyApp.iOS.AppDelegate:FinishedLaunching <0x0027b>
    at System.Object:runtime_invoke_dynamic <0x000f7>
    at <0xffffffff>
    at UIKit.UIApplication:UIApplicationMain <0x00007>
    at UIKit.UIApplication:Main <0x0002b>
    at UIKit.UIApplication:Main <0x00043>
    at MyApp.iOS.Application:Main <0x000ab>

    at System.Object:runtime_invoke_dynamic <0x000f7>

    Anyone any idea what's wrong?

    Thank you!

  • GraverobberGraverobber Member ✭✭✭
    Accepted Answer

    So I solved it all by my own now :)
    I manually adjusted the generated Library code to avoid the need of complicated APIDefinitions. Then I just bound one class and used the methods I added in order to have everything working.

    Thank you.

  • FlorianAuerFlorianAuer DEMember ✭✭
    edited August 2019

    @Graverobber You did it! I monitored the whole topic since start of the last month, but your post didn't come up. Nice work, all on your own. Congrats.
    I couldn't manage to get it working. Is there a way you could provide your binding?

  • GraverobberGraverobber Member ✭✭✭

    Hi @FlorianAuer,

    I'm sorry but I can not post it, as it is corporate property. Anyhow, the Binding alone will not help you as it only binds the methods that I manually added to the generated Xcode library (the one that comes out of Unity).

    This is/was in fact the whole trick, and most likely will not fit all needs, but in order to get the result I work with you need to manually implement some stuff into the library project.
    For example the runEmbeddedWithArgc method that I posted earlier, this one was very hard to bind so I just implemented another method named runEmbeddedWithArgc into the UnityFramework which takes no parameter at all and then I call the runEmbeddedWithArgc method that takes parameters with some default parameters.
    Then I only bind to the one that takes 0 parameters.
    I also added some method to the library that allows to easily add subviews to the UnityView or another one that executes this silly initialisation process (which from my point of view could easily part of the generated code anyway)

    Really sorry that I can't help more, but perhaps it gives you some ideas how to solve it for you :)

  • FlorianAuerFlorianAuer DEMember ✭✭

    Yeah, that's the information I needed. Thanks a lot!
    Good to know that it's possible, if there is some fitting project.
    Was looking for a way to provide it to the community, without modifying the lib. Maybe this defined way mislead my thinking :#

  • GraverobberGraverobber Member ✭✭✭

    @FlorianAuer
    Well, if you find a way to bind it without modifying the lib, I'm the first one to take it :D

    I think what it makes so hard to bind it, compared to the Android version, is the way how it actually needs to be initialised. In Android you have an Activity that handles everything already, so you're good to go, you bind it and then just start the Activity if needed.
    It is even easily possible to write your own C# Activity in order to handle stuff like back click etc. in Xamarin.

    But in iOS the framework needs to be initialised first, and then it is not running in a ViewController that you can just push to, in fact I never fully understand in what kind of container Unity is running under iOS but you have to run it with this embedded call and then focus its window which is not nice in general and even less nice for a Xamarin iOS Binding :)

    What I want to say is, that I have hopes that one day in the future the Unity team will change that and that the exported library will have an easier way to actually use Unity. So far it still is an Alpha version so things can and will change. And then coming with that it might get easier to bind to it :)

  • FilliasFillias Member ✭✭

    Hi

    I am currently trying to implement iOS Bindings for the Unity Framework in Xamarin and the runEmbeddedWithArgc method gives me trouble as well. Is it possible for you to specify which default parameters you feed the new method in Objective C? Also are there other crucial methods I have to call in the Xamarin App to run the Unity Framework.
    I appreciate every help on the topic because it feels like I'm very close but missing the final piece of the puzzle.

    Best regards
    Philipp

  • GraverobberGraverobber Member ✭✭✭

    Hi @Fillias

    I added a function called runEmbedded to the exported Xcode projects UnityFramework.h/main.mm
    It calls the runEmbeddedWithArgc method by passing a native C char** which is filled with the information from [[NSProcessInfo processInfo]arguments];

    This is from some Stackoverflow that I don't remember so I can share it

    Define the array in your main.mm

    char** argsArray = NULL;

    - (char**)getArgumentArray
    {
        NSArray* args = [[NSProcessInfo processInfo]arguments];
    
        unsigned count = [args count];
        char** array = (char **)malloc((count+ 1) * sizeof(char*));
    
        for (unsigned i = 0; i< count; i++)
        {
            array[i] = strdup([[args objectAtIndex:i] UTF8String]);
        }
        array[count] = NULL;
        return array;
    }
    

    As it is a C array it is allocated in memory and you have to free it manually.

    So in your unloadApplication method call

    - (void)freeArray:(char **)array
    {
        if (array != NULL)
        {
            for (unsigned index = 0; array[index] != NULL; index++)
            {
                free(array[index]);
            }
            free(array);
        }
    }
    

    For the dictionary I just pass an empty NSDicitonary [[NSDictionary alloc] init]]

    I hope it will help you.

  • FilliasFillias Member ✭✭

    Thank you! That helped a lot already. I still have an issue now when I try to reference the UnityFramework Instance in Xamarin, that the AppController is Null by default. As I can see it, in the native main.mm this is solved here

    if (![_gUnityFramework appController])
    {
            // unity is not initialized
        [_gUnityFramework setExecuteHeader: &_mh_execute_header];
    }
    

    Can you share any insight on how you solved that issue or how you initialized the framework in xamarin?
    What I am currently trying is to have a button in the main Xamarin app that calls Unity with this method:

    public void StartUnity()
    {
        var fw = UnityFramework.Instance;
        if(fw.AppController == null)
            { System.Diagnostics.Debug.WriteLine("AppController is null"); }
        else
        fw.RunEmbedded();
    }
    

    But I have no idea how the setExecuteHeader function would translate to Xamarin. Also when I try to call this method in the UnityFramework in XCode, I get a build error:

    Undefined symbols for architecture arm64:
    "__mh_execute_header", referenced from:
    +[UnityFramework getInstance] in main.o
    ld: symbol(s) not found for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

  • GraverobberGraverobber Member ✭✭✭

    Yes @Fillias

    I added one more method to the Xcode project that handles the initialisation.
    That way I just call UnityFramework.LoadUnity in my Xamarin project and the internal method will handle this stuff.

    Furthermore I kicked setting the execute header, not sure if it is needed or not.
    But my function just sets the dataBundleId on the _gUnityFramework object, nothing more.

    The steps of my method are:

    Load the Unity Framework with the help of NSBundle Classes.
    Get the Unity Framework instance from the principal class.
    if the app controller is not set
    Set the DataBundleId of the framework to com.unity3d.framework.
    return the unity framework object.

    Create a binding to this function and just init the UnityFramework in Xamarin using it.

  • FilliasFillias Member ✭✭

    Hi,

    I had some time again to work on my integration. Thanks again for you insight @Graverobber. It help a lot in getting progress. After facing one last annoying issue I finally managed to get it to work. But the issue involved the Metal API for the Unity project. When using OpenGL, I can call the Unity scene in Xamarin which is already really nice but since OpenGL is deprecated, I want to be able to use Metal for the future. Can you tell me if you use OpenGL as well and if you ever tried Metal and also faced an error with a Metal texture having a 0 size? I tried different Unity settings already and can't get rid of the issue. I'm using Unity 2019.3.0a8, XCode 11 and Visual Studio 2019 for Mac 8.2.6.

  • GraverobberGraverobber Member ✭✭✭
    edited November 2019

    Hi @Fillias ,

    I just had a look but according to the Unity docs:
    https://docs.unity3d.com/Manual/Metal.html
    it seems that I was using Metal all the time already. (If this is really all that I have to do in order to enable it).
    However the step "Validating Metal API" is not done in my exported Xcode project.
    If you have done it try turning it off it is only for Debug purposes and errors of it will crash your code.

    I never tried working with a 0 size Texture so unfortunately no experiences in that.

    I'm using Unity Version 2019.3.0b1 (beta not alpha!) perhaps updating to it will help you already. My Visual Studio is 8.3.3 for Mac but I don't expect that to influence your results.

    Do you have any crash log to look at?

  • FilliasFillias Member ✭✭

    Updating Unity from Alpha to the newest 2019.3.0b10 Beta Version actually resolved the issue. Not sure if that was the actual problem since I rebuild the whole pipeline but since I did that before with various settings it's probably the reason it works now. Thanks a lot for the continuous support and I'm looking forward to working with the feature now.

  • BIGPIZZA95BIGPIZZA95 Member ✭✭

    @Graverobber , sorry to ask, but is there a possibility for you to write a quick step-by-step on how to integrate a Unity library in Xamarin.Android?
    I'm struggling for days trying to get it working, but a *.so file included in the *.aar lib (maybe even every .so file) can't be found when starting the application and invoking unity startup. What did you do to configure xamarin to find all files included in *.aar file?

  • GraverobberGraverobber Member ✭✭✭
    edited December 2019

    Hi @BIGPIZZA95

    is your Unity project an AR project? I had a similar issue when trying to work with AR.
    My solution (and I hope it will help you as well) was to bundle EVERYTHING into a single aar file.
    The problem is that when bundling the aar normally, Android Studio does not bundle all the reference libraries with it. Therefore they are missing in the end in the aar and Xamarin can not find it. They keyword is fat aar

    However be aware that fat aar is something Google doesn't want to support so I had to rely on a third party Gradle plugin. I used this one:
    https://github.com/kezong/fat-aar-android

    In your project Gradle add the class path
    classpath 'com.kezong:fat-aar:1.2.6'
    (Update the version if possible)

    In unityLibrary module Gradle you have to apply the plugin
    apply plugin: 'com.kezong.fat-aar'

    and then I changed my dependencies from implementation to this:

    implementation(name: 'UnityARCore', ext:'aar')
    embed(name: 'arcore_client', ext:'aar')
    embed(name: 'unityandroidpermissions', ext:'aar')
    

    Then all is bundled into one aar which is much easier to handle.
    Hope it helps if not feel free to provide more details to your problem.

    EDIT
    Just for completeness my problematic .so files where within the arcore_client.aar
    Normally an aar has a classes.jar etc but this special just had .so files in it so it didn't work as supposed to do

  • AndyBarajasAndyBarajas USMember ✭✭

    https://github.com/andressbarajas/UnityBinding

    I was able to figure out how to bind runEmbeddedWithArgc and other stuff. Hopefully helpful to someone.

  • Orlo81Orlo81 Member ✭✭

    Hi @Fillias ,
    Did you do it by @Graverobber by initializing from XCode or by implementing iOS Bindings in Xamarin by calling the runEmbeddedWithArgc method?

    Anyone who has done so could put an example in "code" of how to initialize and load the unity framework would be great, this is the only page on the entire internet that talks about it!

  • FilliasFillias Member ✭✭

    Hi @Orlo81

    I did a hybrid of both. I implemented a runEmbedded method in Xcode like @Graverobber describes and then bin that in Xamarin so I don't have to deal with the arguments in C#.
    I know it's a tricky one and no one talks about it but sadly I can't share my documentation as well because of my companies policy. But once you figure out what causes your issues, it's actually pretty straight forward.

  • Orlo81Orlo81 Member ✭✭
    Hi @Fillias ,
    thanks for answering.
    I think part of the problems is the incompatibility between versions of the programs I use, could you at least tell me the versions of the programs you used? I did the unity (2019.3.0f5) and export the project for iOS, Xcode 10.1 on a Mac, but the xamarin I'm doing it on Windows with vs2017 ...... I don't know if this has to do, since when UnityInitRuntime runs, unity fails and the xamarin app continues to work in the background.
  • FilliasFillias Member ✭✭

    Sure @Orlo81

    What I can tell you is, that I had an issue with Unity 2019.3 when using the early alpha version. Upgrading to beta solved that. So if you are still using an alpha build, that might be the problem. In the package manager in unity you need to update the Ads* package to v3.0 or higher, or disable it completely. The 2.0.8 version of that package can cause trouble.

    Also one important step I missed is setting the Target Membership of the Data folder to UnityFramework in XCode.

    I can't tell you anymore which XCode version I used but I'd say the newest should be fine. I did the whole workflow on Mac OS with Visual Studio for Mac. So not sure if there could be something wrong. Hope that helps

  • Orlo81Orlo81 Member ✭✭
    @Fillias,
    Thank you very much for everything, I will try to do everything on Mac with the instructions you tell me. thanks again.
  • Orlo81Orlo81 Member ✭✭

    Hi @Fillias ,

    Following his instructions, I have made the app in xamarin no longer explode, and the Visual Studio Application Output shows the same output as the XCode when I try from a native ios app by calling the loadUnity to prove it lifts well, but I can't get it the Unity is shown in xamarin although calling that same method from a native ios app picks up well, it's as if I missed the last step:
    This is my code, some advice you could give me for which in the native app it loads well and in xamarin not???:

    • (UnityFramework)loadUnity {
      NSString
      bundlePath = nil;
      bundlePath = [[NSBundle mainBundle] bundlePath];
      bundlePath = [bundlePath stringByAppendingString: @/Frameworks/UnityFramework.framework];

      NSBundle* bundle = [NSBundle bundleWithPath: bundlePath];
      if ([bundle isLoaded] == false) [bundle load];

      UnityFramework* ufw = [bundle.principalClass getInstance];
      if (![ufw appController])
      {
      // unity is not initialized
      //[ufw setExecuteHeader: &_mh_execute_header];
      }
      [ufw setDataBundleId: "com.unity3d.framework"];

      // Grab the arguments used to start the process (apparently Unity needs them)
      NSArray* arguments = [[NSProcessInfo processInfo] arguments];
      NSInteger count = [arguments count];
      char **array = (char **)malloc((count + 1) * sizeof(char*));

      for (NSInteger i = 0; i < count; i++) {
      array[i] = strdup([[arguments objectAtIndex:i] UTF8String]);
      }
      array[count] = NULL;
      char** argv = array;

      NSDictionary* nsdic = [[NSDictionary alloc] init];
      // char* argv[]
      [ufw runEmbeddedWithArgc: 1 argv: argv appLaunchOpts: nsdic];
      return ufw;
      }

    Regards...

  • Orlo81Orlo81 Member ✭✭

    Hi @Graverobber ,
    After reviewing all the indications I think one of the things I am missing is: "and then focus its window which is not nice in general and even less nice for a Xamarin iOS Binding"
    Well, as I commented to @Fillias, I see that the Unity loads well without errors but I can not show it in the app, it is as if the window needs to be focused
    This should be done on the side of Xamarin or Unity ???

    Sorry for the inconvenience, it's not easy to do something you've never worked on.

  • GraverobberGraverobber Member ✭✭✭
    edited March 2020

    @Orlo81
    What I did was adding an additional method to the Xcode library called showUnityWindow which does nothing but:

    [[[self appController] window] makeKeyAndVisible];
    If you have access to AppController from within your Xamarin project you can call it from there as well.

    All I do in Xamarin is:

    UnityFramework ufw = UnityFramework.LoadUnity();
    //Start unity
    ufw.RunEmbedded();
    ufw.ShowUnityWindow() // [[[self appController] window] makeKeyAndVisible];
    

    and that's it.
    Hope it helps!

  • Orlo81Orlo81 Member ✭✭

    @Graverobber ,
    Thank you very much for responding, I will try these changes right away.
    Getting so far has been an achievement.
    Regards.

  • Orlo81Orlo81 Member ✭✭
    edited March 2020

    Hi @Graverobber and @Fillias ,
    After a thousand tries I managed to load the Unity Framework into a xamarin forms project on ios!!!

    One of the problems I had is that I couldn't load it in a xamarin ios project (not xamarin forms) -> Single View App (one-page iOS application), nor in a native one of ios in xcode with the following config in the Info.plist:
    " UIApplicationSceneManifest

    UIApplicationSupportsMultipleScenes

    UISceneConfigurations

    UIWindowSceneSessionRoleApplication


    UISceneConfigurationName
    Default Configuration
    UISceneDelegateClassName
    SceneDelegate
    UISceneStoryboardFile
    Main



    "

    Apparently in this type of project the unity loads but is not shown. However in the xamarin forms ios it shows fine. It's like the view mechanism works differently and unity doesn't load in the right place.

    At least where I needed it to load, it loaded well.

  • SaschaMartinetzSaschaMartinetz USMember ✭✭
    edited April 2020

    Hey guys...

    I am following this thread for a while now because it seems this is the only one discussing this issue.
    I tried all the suggestions and hints you guys dropped and even tried solving it using the Unity Binding from @AndyBarajas
    he posted a while ago without much success.

    As suggested I tried adding a function to the XCode Project in Classes/main.mm like this:
    `- (void)runEmbedded
    {
    NSArray* arguments = [[NSProcessInfo processInfo] arguments];
    NSInteger count = [arguments count];
    char **array = (char **)malloc((count + 1) * sizeof(char*));

    for (NSInteger i = 0; i < count; i++) {
        array[i] = strdup([[arguments objectAtIndex:i] UTF8String]);
    }
    array[count] = NULL;
    char** argv = array;
    
    NSDictionary* nsdic = [[NSDictionary alloc] init];
    [self runEmbeddedWithArgc: 1 argv: argv appLaunchOpts: nsdic];
    

    }`

    I try to get the instance doing this...
    [Static, Export("UnityFrameworkLoad")] UnityFramework UnityFrameworkLoad();

    then I try to call runEmbedded like that..
    UnityFramework ufw = UnityFramework.UnityFrameworkLoad(); ufw.RunEmbedded(); ufw.ShowUnityWindow();

    ... all I get is an Error about calling a function that does not exist.

    Is the class I am using (classes/main.mm) even correct? There is another main.mm in the MainApp folder!?
    I am aware that I have to first initialize Unity, then run it and then showing the window but it seems everything I tried is ending up in my App just crashing.

    My current setup is multi platform (Android, iOS, UWP) with shared code. I included another Project for the Unity Binding holding the reference to the Unity.Framework.

    Can anybody point me in the right direction please?

    Regards,
    Sascha

  • GraverobberGraverobber Member ✭✭✭
    edited April 2020

    @SaschaMartinetz ... all I get is an Error about calling a function that does not exist.

    Could you specify which class is the one missing?

  • SaschaMartinetzSaschaMartinetz USMember ✭✭

    @Graverobber said:

    @SaschaMartinetz ... all I get is an Error about calling a function that does not exist.

    Could you specify which class is the one missing?

    Thank you for the quick response!! I will let you know as soon as I can get back to my project.

  • SaschaMartinetzSaschaMartinetz USMember ✭✭

    @Graverobber said:

    @SaschaMartinetz ... all I get is an Error about calling a function that does not exist.

    Could you specify which class is the one missing?

    Ok.. today had some time to go at it again..
    It's not a class that seems to be missing but it looks like the function/method could not be found.

    I get this exception
    Objective-C exception thrown. Name: NSInvalidArgumentException Reason: +[UnityFramework UnityFrameworkLoad]: unrecognized selector sent to class 0x10a1f7298

    Regards

  • GraverobberGraverobber Member ✭✭✭

    Hmm it is difficult to say without seeing your code.
    My first impression is that you need to check the ApiDefinition in your iOS Binding project.
    Check if the method is actually named UnityFrameworkLoad within your iOS project. Check that it is correctly assigned within the Binding project.

    If you can, you could post your Api Definition and your iOS main.mm here.

  • SaschaMartinetzSaschaMartinetz USMember ✭✭
    edited April 2020

    @Graverobber said:
    Hmm it is difficult to say without seeing your code.
    My first impression is that you need to check the ApiDefinition in your iOS Binding project.
    Check if the method is actually named UnityFrameworkLoad within your iOS project. Check that it is correctly assigned within the Binding project.

    If you can, you could post your Api Definition and your iOS main.mm here.

    I understand...

    I checked my API definition and the method UnityFrameworkLoad is declared like this in my Interface:

    [Static, Export("UnityFrameworkLoad")] UnityFramework UnityFrameworkLoad();

    My main.mm is looking like this in my iOS project:

    #include "RegisterFeatures.h"
    #include <csignal>
    #include "UnityInterface.h"
    #include "../UnityFramework/UnityFramework.h"

    void UnityInitTrampoline();

    // WARNING: this MUST be c decl (NSString ctor will be called after +load, so we cant really change its value) const char* AppControllerClassName = "UnityAppController";

    #if UNITY_USES_DYNAMIC_PLAYER_LIB
    extern "C" void SetAllUnityFunctionsForDynamicPlayerLib();
    #endif

    extern "C" void UnitySetExecuteMachHeader(const MachHeader* header);

    extern "C" attribute((visibility("default"))) NSString* const kUnityDidUnload;
    extern "C" attribute((visibility("default"))) NSString* const kUnityDidQuit;

    @implementation UnityFramework
    {
    int runCount;
    }

    UnityFramework* _gUnityFramework = nil;

    • (UnityFramework*)getInstance
      {
      if (_gUnityFramework == nil)
      {
      _gUnityFramework = [[UnityFramework alloc] init];
      }
      return _gUnityFramework;
      }

    • (UnityAppController*)appController
      {
      return GetAppController();
      }

    • (void)setExecuteHeader:(const MachHeader*)header
      {
      UnitySetExecuteMachHeader(header);
      }

    • (void)sendMessageToGOWithName:(const char)goName functionName:(const char)name message:(const char*)msg
      {
      UnitySendMessage(goName, name, msg);
      }

    • (void)registerFrameworkListener:(id)obj
      {
      #define REGISTER_SELECTOR(sel, notif_name) \
      if([obj respondsToSelector:sel]) \
      [[NSNotificationCenter defaultCenter] addObserver:obj selector:sel name:notif_name object:nil];

      REGISTER_SELECTOR(@selector(unityDidUnload:), kUnityDidUnload);
      REGISTER_SELECTOR(@selector(unityDidQuit:), kUnityDidQuit);

    #undef REGISTER_SELECTOR
    }

    • (void)unregisterFrameworkListener:(id)obj
      {
      [[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityDidUnload object: nil];
      [[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityDidQuit object: nil];
      }

    • (void)frameworkWarmup:(int)argc argv:(char*[])argv
      {
      #if UNITY_USES_DYNAMIC_PLAYER_LIB
      SetAllUnityFunctionsForDynamicPlayerLib();
      #endif

      UnityInitTrampoline();
      UnityInitRuntime(argc, argv);

      RegisterFeatures();

      // iOS terminates open sockets when an application enters background mode.
      // The next write to any of such socket causes SIGPIPE signal being raised,
      // even if the request has been done from scripting side. This disables the
      // signal and allows Mono to throw a proper C# exception.
      std::signal(SIGPIPE, SIG_IGN);
      }

    • (void)setDataBundleId:(const char*)bundleId
      {
      UnitySetDataBundleDirWithBundleId(bundleId);
      }

    • (void)runUIApplicationMainWithArgc:(int)argc argv:(char*[])argv
      {
      self->runCount += 1;
      [self frameworkWarmup: argc argv: argv];
      UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);
      }

    UnityFramework* UnityFrameworkLoad()
    {
    NSString* bundlePath = nil;
    bundlePath = [[NSBundle mainBundle] bundlePath];
    bundlePath = [bundlePath stringByAppendingString: @/Frameworks/UnityFramework.framework];

    NSBundle* bundle = [NSBundle bundleWithPath: bundlePath];
    if ([bundle isLoaded] == false) [bundle load];
    
    UnityFramework* ufw = [bundle.principalClass getInstance];
    if (![ufw appController])
    {
        // unity is not initialized
        [ufw setExecuteHeader: &_mh_execute_header];
    }
    else
        `[ufw setDataBundleId: "com.unity3d.framework"];
    
    return ufw;
    

    }

    • (void)runEmbedded
      {
      NSArray* arguments = [[NSProcessInfo processInfo] arguments];
      NSInteger count = [arguments count];
      char **array = (char **)malloc((count + 1) * sizeof(char*));

      for (NSInteger i = 0; i < count; i++) {
      array[i] = strdup([[arguments objectAtIndex:i] UTF8String]);
      }
      array[count] = NULL;
      char** argv = array;

      NSDictionary* nsdic = [[NSDictionary alloc] init];
      [self runEmbeddedWithArgc: 1 argv: argv appLaunchOpts: nsdic];
      }

    • (void)runEmbeddedWithArgc:(int)argc argv:(char[])argv appLaunchOpts:(NSDictionary)appLaunchOpts
      {
      if (self->runCount)
      {
      // initialize from partial unload ( sceneLessMode & onPause )
      UnityLoadApplicationFromSceneLessState();
      [self pause: false];
      [self showUnityWindow];
      }
      else
      {
      // full initialization from ground up
      [self frameworkWarmup: argc argv: argv];

      id app = [UIApplication sharedApplication];
      
      id appCtrl = [[NSClassFromString([NSString stringWithUTF8String: AppControllerClassName]) alloc] init];
      [appCtrl application: app didFinishLaunchingWithOptions: appLaunchOpts];
      
      [appCtrl applicationWillEnterForeground: app];
      [appCtrl applicationDidBecomeActive: app];
      

      }

      self->runCount += 1;
      }

    • (void)unloadApplication
      {
      UnityUnloadApplication();
      }

    • (void)quitApplication:(int)exitCode
      {
      UnityQuitApplication(exitCode);
      }

    • (void)showUnityWindow
      {
      [[[self appController] window] makeKeyAndVisible];
      }

    • (void)pause:(bool)pause
      {
      UnityPause(pause);
      }

    @end

    #if TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR
    #include <pthread.h>

    extern "C" int pthread_cond_init$UNIX2003(pthread_cond_t *cond, const pthread_condattr_t *attr)
    { return pthread_cond_init(cond, attr); }
    extern "C" int pthread_cond_destroy$UNIX2003(pthread_cond_t *cond)
    { return pthread_cond_destroy(cond); }
    extern "C" int pthread_cond_wait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex)
    { return pthread_cond_wait(cond, mutex); }
    extern "C" int pthread_cond_timedwait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex,
    const struct timespec *abstime)
    { return pthread_cond_timedwait(cond, mutex, abstime); }

    #endif // TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR

    ps: posting code here does not really work for me.. sorry for that, i tried my best to make it somewhat readable :(

  • SaschaMartinetzSaschaMartinetz USMember ✭✭

    @Graverobber
    I can't belive it but finally after many many tries.. I got it working!
    Thanks to your hints and the work of @AndyBarajas

    One thing I noticed however, I get Linker Errors in my Xamarin Project if I try to run this in a simulator.

    Regards

  • GraverobberGraverobber Member ✭✭✭

    Yes, I also never had it running on the simulator. I think that's a unity limitation but not sure :D

    Nice that it works now, congrats!

  • SaschaMartinetzSaschaMartinetz USMember ✭✭
    edited April 2020

    Oh btw..
    did you manage to utilize their QuitHandler properly?
    I would like to quit the Unity view and then have Xamarin switch pages. I succeeded as far as using the handler and then loading my MasterDetailPage again, but it seems the UnityView is still open but invisible somehow!? I can see the Xamarin page just fine but can not click on anything anymore. Have you experienced something similar?

    I tried unloadApplication as well as quitApplication but both methods just end up in a long Managed Stacktrace...

    =================================================================
    Managed Stacktrace:
    =================================================================
    at <unknown> <0xffffffff> at ApiDefinition.Messaging:void_objc_msgSend <0x00007> at NativeLibrary.UnityFramework:UnloadApplication <0x0010f> at <BackToMainWindowDel>d__10:MoveNext <0x0032f> at MoveNextRunner:InvokeMoveNext <0x0009b> at System.Threading.ExecutionContext:RunInternal <0x001ab> at System.Threading.ExecutionContext:Run <0x0002b> at MoveNextRunner:Run <0x000c7> at System.Threading.Tasks.AwaitTaskContinuation:InvokeAction <0x00053> at System.Threading.Tasks.AwaitTaskContinuation:RunCallback <0x00063> at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation:Run <0x0013b> at System.Threading.Tasks.Task:FinishContinuations <0x002ef> at System.Threading.Tasks.Task:FinishStageThree <0x0009f> at System.Threading.Tasks.Task1:TrySetResult <0x00133>
    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1:SetResult <0x000db> at <PopAsync>d__47:MoveNext <0x00807> at MoveNextRunner:InvokeMoveNext <0x0009b> at System.Threading.ExecutionContext:RunInternal <0x001ab> at System.Threading.ExecutionContext:Run <0x0002b> at MoveNextRunner:Run <0x000c7> at System.Threading.Tasks.AwaitTaskContinuation:InvokeAction <0x00053> at System.Threading.Tasks.AwaitTaskContinuation:RunCallback <0x00063> at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation:Run <0x0013b> at System.Threading.Tasks.Task:FinishContinuations <0x002ef> at System.Threading.Tasks.Task:FinishStageThree <0x0009f> at System.Threading.Tasks.Task1:TrySetResult <0x00133>
    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1:SetResult <0x000db> at <PopAsyncInner>d__71:MoveNext <0x004a7> at MoveNextRunner:InvokeMoveNext <0x0009b> at System.Threading.ExecutionContext:RunInternal <0x001ab> at System.Threading.ExecutionContext:Run <0x0002b> at MoveNextRunner:Run <0x000c7> at System.Threading.Tasks.AwaitTaskContinuation:InvokeAction <0x00053> at System.Threading.Tasks.AwaitTaskContinuation:RunCallback <0x00063> at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation:Run <0x0013b> at System.Threading.Tasks.Task:FinishContinuations <0x002ef> at System.Threading.Tasks.Task:FinishStageThree <0x0009f> at System.Threading.Tasks.Task1:TrySetResult <0x00133>
    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1:SetResult <0x000db> at <Xamarin-Forms-INavigationPageController-RemoveAsyncInner>d__72:MoveNext <0x007a3> at MoveNextRunner:InvokeMoveNext <0x0009b> at System.Threading.ExecutionContext:RunInternal <0x001ab> at System.Threading.ExecutionContext:Run <0x0002b> at MoveNextRunner:Run <0x000c7> at System.Threading.Tasks.AwaitTaskContinuation:InvokeAction <0x00053> at System.Threading.Tasks.AwaitTaskContinuation:RunCallback <0x00063> at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation:Run <0x0013b> at System.Threading.Tasks.Task:FinishContinuations <0x002ef> at System.Threading.Tasks.Task:FinishStageThree <0x0009f> at System.Threading.Tasks.Task1:TrySetResult <0x000fb>
    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1:SetResult <0x000f7> at <OnPopViewAsync>d__50:MoveNext <0x0073f> at MoveNextRunner:InvokeMoveNext <0x0009b> at System.Threading.ExecutionContext:RunInternal <0x001ab> at System.Threading.ExecutionContext:Run <0x0002b> at MoveNextRunner:Run <0x000c7> at System.Threading.Tasks.AwaitTaskContinuation:InvokeAction <0x00053> at System.Threading.Tasks.AwaitTaskContinuation:RunCallback <0x00063> at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation:Run <0x0013b> at System.Threading.Tasks.Task:FinishContinuations <0x002ef> at System.Threading.Tasks.Task:FinishStageThree <0x0009f> at System.Object:gsharedvt_out_sig <0x00023> at <unknown> <0xffffffff> at System.Threading.Tasks.Task1:TrySetResult <0x0009c>
    at System.Threading.Tasks.TaskCompletionSource1:TrySetResult <0x00014> at System.Threading.Tasks.TaskCompletionSource1:SetResult <0x0000c>
    at <>c__DisplayClass54_0:b__3 <0x00012>
    at :invoke_void <0xffffffff>
    at <0xffffffff>
    at System.Object:__interp_lmf_mono_interp_entry_from_trampoline <0x00007>
    at Foundation.NSAsyncActionDispatcher:Apply <0x00023>
    at System.Object:runtime_invoke_dynamic <0x0010f>
    at <0xffffffff>
    at UIKit.UIApplication:UIApplicationMain <0x00007>
    at UIKit.UIApplication:Main <0x0002f>
    at UIKit.UIApplication:Main <0x00043>
    at UnityEmbed.iOS.Application:Main <0x0007f>
    at System.Object:runtime_invoke_dynamic <0x0010f>
    =================================================================`

    Regards

  • GuillaumeDaguinGuillaumeDaguin USUniversity

    Hello,
    @FlorianAuer @SaschaMartinetz have you come up with a solution that works on iOS?
    Because of the difficulty of such binding (it seems really complex, much more than Android one !), could you provide a working test project on Xamarin iOS?
    Thank you guys !

  • YusefYusef Member ✭✭

    Hi guys,
    @Graverobber could you help me with this one? I have little to none experience with native development and none with xamarin, but i wold like to implemente the unity lib in xamarin for a project Im working on, i managed to create de binding for the unity framework using this post, heres where im at in my github ( cant share links, this is my user and repo name on gitgub .../yusefrich/MB--unity-as-lib-xamarin ) but thats aboult it.. How to i can bind a function to a button and call the initialization of the unity view? can someone link me a repo or a gist with that implementation?

    Thank you guys!!!!!

  • GraverobberGraverobber Member ✭✭✭

    Hi @Yusef,

    from what I see in your code you want to call unity from your Forms Page.
    However your Binding is for iOS so it will work only in iOS.
    You have to reference it into your iOS project. Then you have two options:
    Either you use the Messagings center https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/messaging-center in order to send a message from your forms project to the iOS one that indicates when you want to start Unity or you implement a dependency service to achieve the same goal https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction
    The messaging center for sure is easier to use/understand for beginners.

    Then when you receive the message in, for example, your AppDelegate you just use the methods of your Binding to start Unity as you would do it natively.

    Hope it helps.

  • FlorianAuerFlorianAuer DEMember ✭✭

    @GuillaumeDaguin Yeah, it's working as described by the guys wrote in this thread. Unfortunately I can't give you the sourcecode, wrote it for a client.

    @all thank you very much for all the info. All combined worked like a charm :)

Sign In or Register to comment.