Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Integration Unity as a library in native iOS app

Discussion in '2019.3 Beta' started by PavelLU, May 27, 2019.

  1. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    This post explains how to include Unity as a Library into native iOS application. You can read more about Unity as a Library.

    Pre Requirements:
    1. Get source
    • Clone or Download GitHub repo uaal-example. It includes
      folderStructure.png
      • UnityProject - this is a simple demo project made with Unity which will be integrated to the standard iOS application. Assets / Plugins / iOS files used to communicate from Unity player to Native app
      • NativeiOSApp - this is simple Xcode single view application where we want to integrate our Unity project. It has some UI and is prepared to load player with UnityFrameworkLoad()
    2. Generate Xcode project for iOS
    Nothing new here just generate Xcode project as usual
    • from Unity Editor open UnityProject
    • remove or update Ads package to v 3.* (2.0.8 version is not compatible with Unity as a Library) (Menu / Window / Package Manager)
    • set valid Bundle Identification and Signing Team ID ( to avoid Xcode signing issues on later steps ) (Menu / Edit / Player Settings / Player / iOS Setting tab / Identification Section)
    • select and switch to platform iOS (Menu / File / Builds Settings)
      • Build inside UnityProject to iosBuild folder
        image11.png
    3. Setup Xcode workspace
    Xcode workspace allows to work on multiple projects simultaneously and combine their products

    • open NativeiOSApp.xcodeproj from Xcode
    • create workspace and save it at UaaLExample/both.xcworkspace. (File / New / Workspace) image8.png
    • close NativeiOSApp.xcodeproj project all Next steps are done from just created Workspace project
    • add NativeiOSApp.xcodeproj and generated Unity-iPhone.xcodeproj from step #2 to workspace on a same level ( File / Add Files to “both” )
      image3.png
    4. Add UnityFramework.framework
    With this step we add Unity player in form of framework to NativeiOSApp, it does not change behavior of NativeiOSApp yet
    • selected NativeiOSApp target from NativeiOSApp project
    • in General / Embedded Binaries press +
    • select Unity-iPhone/Products/UnityFramework.framework
    • remove UnityFramework.framework from Linked Frameworks and Libraries ( select it and press - ) image1.png
     
    Last edited: Nov 5, 2019
    chaobaji and smartinetz like this.
  2. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    5. Expose NativeCallProxy.h
    Native application implements NativeCallsProtocol defined in following file.
    • find and select Unity-iPhone / Libraries / Plugins / iOS / NativeCallProxy.h
    • enable UnityFramework in Target Membership and set Public header visibility (small dropdown on right side to UnityFramework)
      image7.png
    6. Make Data folder to be part of the UnityFramework
    By default Data folder is part of Unity-iPhone target, we change that to make everything encapsulated in one single framework file.
    • change Target Membership for Data folder to UnityFramework
      image4.png
    • (optional) after previous change for Unity-iPhone project to continue to work Unity player need to point to a new place where Data is located by calling from Unity-iPhone/MainApp/main.mm:
      Code (CSharp):
      1. [ufw setDataBundleId: "com.unity3d.framework"];
      On Demand Resources are not supported in this case. To make them work instead of the calls above you need to copy Data folder to your native application (With script at Build Phases) and skip a calls above since by default Data folder expected to be in mainBundle.
      image9.png
     
    smartinetz and pratikp_unity like this.
  3. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    Workspace is ready
    Everything is ready to build, run and debug for both projects: Unity-iPhone and NativeiOSApp (select scheme NativeiOSApp or Unity-iPhone)
    image6.png

    If all went successfully at this point you should be able to run NativeiOSApp:
    workspaceIsReady.png


    Key point
    Unity player is controlled with UnityFramework object. To get it you call UnityFrameworkLoad (it loads UnityFramework.framework if it wasn't, and returns singleton instance to UnityFramework class observe Unity-iPhone/UnityFramework/UnityFramework.h for its API ).
    Observe UnityFrameworkLoad in: NativeiOSApp/NativeiOSApp/MainViewController.mm or in Unity-iPhone/MainApp/main.mm

    Code (csharp):
    1. #include <UnityFramework/UnityFramework.h>
    2.  
    3. UnityFramework* UnityFrameworkLoad()
    4. {
    5.     NSString* bundlePath = nil;
    6.     bundlePath = [[NSBundle mainBundle] bundlePath];
    7.     bundlePath = [bundlePath stringByAppendingString: @"/Frameworks/UnityFramework.framework"];
    8.  
    9.     NSBundle* bundle = [NSBundle bundleWithPath: bundlePath];
    10.     if ([bundle isLoaded] == false) [bundle load];
    11.  
    12.     UnityFramework* ufw = [bundle.principalClass getInstance];
    13.     if (![ufw appController])
    14.     {
    15.         // Initialize Unity for a first time
    16.         [ufw setExecuteHeader: &_mh_execute_header];    
    17.  
    18.         // Keep in sync with Data folder Target Membership setting
    19.         [ufw setDataBundleId: "com.unity3d.framework"];
    20.    
    21.     }
    22.     return ufw;
    23. }
     
    Last edited: Nov 5, 2019
  4. kiozer001_unity

    kiozer001_unity

    Joined:
    May 28, 2019
    Posts:
    3


    One question, I'm a little new to unity, I've already exported my unity project but it does not include the Unityframewrok, is there a series of specific steps to export the project correctly? Greetings!
     
  5. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    All Xcode generated projects with Unity version 2019.3.a2+ will have new structure: launcher+UnityFramework ( there is no specific steps to do for that), please double check your unity version.
     
  6. kiozer001_unity

    kiozer001_unity

    Joined:
    May 28, 2019
    Posts:
    3
    It is true I have a version below, I had that it was the most stable version since the ones you mention is an alpha, but then I will update and follow the tutorial, thanks for the help
     
  7. yurykorzun

    yurykorzun

    Joined:
    Oct 29, 2015
    Posts:
    41
  8. csz19941105

    csz19941105

    Joined:
    Jun 20, 2019
    Posts:
    3
    Hi bosses ,if my Unity3D project change,Which files I need to replace in the IOS project?or I need intergation again?
     
  9. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    You need to upgrade your project to Unity 2019.3.a2+ version first and then generate Xcode project.
     
  10. csz19941105

    csz19941105

    Joined:
    Jun 20, 2019
    Posts:
    3
    Thank you for your answer. I mean after integration, what should I do if my Unity needs to add new content? Replace or reintegrate
     
  11. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    You do integration once then generation of Xcode project with Append and Replace from Unity will work just fine and you wont need to reintegrate again.
     
    kamran-bigdely likes this.
  12. csz19941105

    csz19941105

    Joined:
    Jun 20, 2019
    Posts:
    3
    Thank you very much, hope you give more detailed tutorials!:p
     
  13. DirkDenzer

    DirkDenzer

    Joined:
    May 8, 2019
    Posts:
    11
    I tried to follow this but I can't get it to work.

    First of all my unity xcodeproj is missing the NativeProxyCall. In fact it is missing the whole Plugins folder, there is only Libraries and that's it.

    Second, I don't understand how I can present a second ViewController as my Unity project.
    I was expecting something similar to the Android one, which I got running just fine, where I "just" have to integrate the generated framework and then can push to UnityViewController (Similar to Activity under Android) but that seems not to be the case?
     
  14. murali_unity224

    murali_unity224

    Joined:
    Jun 27, 2019
    Posts:
    1
    I got the issue with unity2019.a7 version.
    MTLTextureDescriptor has width of zero.
     
    SpyDev likes this.
  15. createtheimaginable

    createtheimaginable

    Joined:
    Jan 30, 2019
    Posts:
    29
    So I am an iOS developer more than I am a Unity developer. This sounds great but can you explain what functionally "Unity as a Library" provides? Maybe explain it with some use cases? At first glance this sounds too good to be true! ;)

    For example, can I switch from my natively running iOS Apps view to a Unity running view and then back to my native iOS view again? I think the AR Ads use case was mentioned... Can I have my natively running iOS app switch to a visible Unity Engine C# view and then when the Unity AR Ad is finished can I switch back to my view running Objective C native code programmatically? Also, can those 2 views pass data back and forth to each other?
     
  16. fanxiangyang

    fanxiangyang

    Joined:
    Jul 2, 2019
    Posts:
    2
    validateTextureDimensions, line 1074: error 'MTLTextureDescriptor has width of zero.'
    Code (CSharp):
    1. extern "C" void CreateSystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface)
    2. extern "C" void CreateRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface)
    3.  
    4. so i add code
    5. surface->targetW=[UIScreen mainScreen].bounds.size.width*2;
    6.  surface->targetH=[UIScreen mainScreen].bounds.size.height*2;
    7.  surface->systemW=[UIScreen mainScreen].bounds.size.width*2;
    8.  surface->systemH=[UIScreen mainScreen].bounds.size.height*2;
    9.  
    10. 2==[UIScreen mainScreen].scale
    11.  
    12. why width and height==0?
    13.  
    14.  
     
    Last edited: Jul 2, 2019
    jiexiangshen likes this.
  17. naveen90

    naveen90

    Joined:
    Apr 15, 2013
    Posts:
    3
    Hi Friends,

    I am checking with full project and running it on Xcode 10.1. When I run NativeIosApp scheme. It shows

    error
    'UnityFramework/UnityFramework.h' file not found

    Its not loading UnityFramework class properly. I did all steps of loading UnityFramework.framework .

    Can anybody knows how to fix this?

    Thanks
     
  18. ArpitTyagi01

    ArpitTyagi01

    Joined:
    Feb 21, 2018
    Posts:
    14
    Hey Everyone , i am trying to do all the needful with this project but facing the issue of
    'MTLTextureDescriptor has width of zero.'

    Can anyone help me out with this .
    Thanks in advance.
     
  19. fanxiangyang

    fanxiangyang

    Joined:
    Jul 2, 2019
    Posts:
    2
    me to ; look 16#,but,don't know why?
     
  20. IevaUnity

    IevaUnity

    Unity Technologies

    Joined:
    Dec 15, 2014
    Posts:
    6
    Hey there. Thanks to all for letting us know about this issue! I have checked it and I can say that is a Unity Metal regression. Bug will be reported. For now you can use this workaround:
    Screenshot 2019-07-03 at 13.32.45.png
    You can see that `&& params.renderW != 0 && params.renderH != 0` should be added to Unity-iPhone->Classes->Unity->DisplayManager.mm 145 line
     
    SpyDev, ArpitTyagi01 and PavelLU like this.
  21. ArpitTyagi01

    ArpitTyagi01

    Joined:
    Feb 21, 2018
    Posts:
    14
    Thank you @levaUnity for the quick response , i have a question this library can only be used to initialise Unity into iOS or can we load a particular scene as well , like if i want to load only a scene which is on 3rd index , is this possible with this library ?
     
  22. gyorics

    gyorics

    Joined:
    Feb 22, 2017
    Posts:
    1
    I have the same error... Can anybody knows how to fix this?
     
    AkhilRaja likes this.
  23. cyliax

    cyliax

    Joined:
    Feb 25, 2014
    Posts:
    18
    Thanks for the detailed explanation but I have the same problem using your full example:

    'UnityFramework/UnityFramework.h' file not found

    Any ideas?

    Update: OK, seems to be my fault. Your example is running fine on a device but not in simulator.
     
    Last edited: Jul 12, 2019
    FakeBeard and dabo248 like this.
  24. cyliax

    cyliax

    Joined:
    Feb 25, 2014
    Posts:
    18
    How about integrating Vuforia AR framework into that workflow? What additional steps would I have to take?

    Update: I managed it to embed easyAR without any problems, camera view und target tracking, but no success with Vuforia so far.
     
    Last edited: Jul 12, 2019
  25. cyliax

    cyliax

    Joined:
    Feb 25, 2014
    Posts:
    18
    As you can use SendMessage to public receivers methods it should not be a problem to start your Unity project in a loading scene, wait for that call with a parameter and load the scene you like after Unity was loaded successfully.
     
  26. cyliax

    cyliax

    Joined:
    Feb 25, 2014
    Posts:
    18
    This is exactly what you can do. Have a look at the full example and you'll find out, that you start a native written app than load and switch to Unity and go back to your native entry point. You can pass messages with params from native to Unity but I don't know if that is possible from Unity to native (but I'll find out).
     
    createtheimaginable likes this.
  27. psydent

    psydent

    Joined:
    Feb 11, 2013
    Posts:
    12
    Of course you can call native functions with params from Unity. Unless something else is meant/desired.
     
  28. psydent

    psydent

    Joined:
    Feb 11, 2013
    Posts:
    12
    Some questions @PavelLU
    1. What was behind the decision to change the usual target Unity-iPhone to use UnityFramework?
    2. Why not have Data be in UnityFramework's PBXResourcesBuildPhase by default? It would pretty much remove the step 6. Make Data folder to be part of the UnityFramework thus making it easier for users. Only because it's mentioned, I'm guessing to allow On Demand Resources for Data, but that seems like an obscure use case.
    3. Regarding bundle and path stuff, why not automate it? I filed bug 1169886 for this.
     
  29. DirkDenzer

    DirkDenzer

    Joined:
    May 8, 2019
    Posts:
    11
    Once the unity view is started by
    [[self ufw] runEmbeddedWithArgc:

    how can we navigate back to the previous ViewController?
     
  30. tkudari

    tkudari

    Joined:
    Nov 2, 2014
    Posts:
    2
    Great post! Looks like using the ARFoundation and AR Kit XR plugins into the sample project linked above) generates what seems to be IL2CPP related link errors in XCode when building.

    When the plugins aren't installed, the sample project seems to work fine on the iOS device .

    Versions being used:
    Code (CSharp):
    1. Unity: 2019.3.0a2
    2. ARFoundation: 2.0.2 (also tried 1.1.0 and 1.0.0)
    3. ARKit XR plugin: 2.0.1 (also tried 1.0.0)
    4. XCode: 10.1
    5. iPhone 8 running iOS 12.2
    Code (CSharp):
    1. Undefined symbols for architecture arm64:
    2.   "_FrameReceivedEventArgs_t4637B6D2FC28197602B18C1815C4A778645479DD_marshal_pinvoke_cleanup", referenced from:
    3.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    4.   "_GestureManipulationEvent_t80F0163CC6437F2E1BC5B773E9599AF499D08E4F_marshal_pinvoke", referenced from:
    5.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    6.   "_GestureManipulationEvent_t80F0163CC6437F2E1BC5B773E9599AF499D08E4F_marshal_pinvoke_cleanup", referenced from:
    7.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    8.   "_GestureNavigationEvent_t3718B4FDF2C71A07DFAB23CE2E27D1D022417866_marshal_pinvoke", referenced from:
    9.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    10.   "_GestureRecognitionEvent_tBB5EFD6FF7697E5F8FDFB64BA9A51003282AEE68_marshal_pinvoke", referenced from:
    11.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    12.   "_GestureRecognitionEvent_tBB5EFD6FF7697E5F8FDFB64BA9A51003282AEE68_marshal_pinvoke_back", referenced from:
    13.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    14.   "_GestureTappedEvent_t793E61A597E40572998004754809BBF49D738535_marshal_pinvoke_back", referenced from:
    15.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    16.   "_GestureTappedEvent_t793E61A597E40572998004754809BBF49D738535_marshal_pinvoke_cleanup", referenced from:
    17.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    18.   "_MeshGenerationResult_t24F21E71F8F697D7D216BA4F3F064FB5434E6056_marshal_pinvoke", referenced from:
    19.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    20.   "_MeshGenerationResult_t24F21E71F8F697D7D216BA4F3F064FB5434E6056_marshal_pinvoke_back", referenced from:
    21.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    22.   "_PlaneAddedEventArgs_t06BF8697BA4D8CD3A8C9AB8DF51F8D01D2910002_marshal_pinvoke_back", referenced from:
    23.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    24.   "_PlaneRemovedEventArgs_t21E9C5879A8317E5F72263ED2235116F609E4C6A_marshal_pinvoke_cleanup", referenced from:
    25.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    26.   "_PlaneUpdatedEventArgs_tD63FB1655000C0BC238033545144C1FD81CED133_marshal_pinvoke", referenced from:
    27.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    28.   "_PointCloudUpdatedEventArgs_tE7E1E32A6042806B927B110250C0D4FE755C6B07_marshal_pinvoke", referenced from:
    29.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    30.   "_PointCloudUpdatedEventArgs_tE7E1E32A6042806B927B110250C0D4FE755C6B07_marshal_pinvoke_back", referenced from:
    31.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    32.   "_SessionTrackingStateChangedEventArgs_tE4B00077E5AAE143593A0BB3FA2C57237525E7BA_marshal_pinvoke", referenced from:
    33.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    34.   "_XRRenderPass_tEFEBF289C538809498F1828580181B42CE0FD7C8_marshal_pinvoke_back", referenced from:
    35.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    36.   "_XRRenderPass_tEFEBF289C538809498F1828580181B42CE0FD7C8_marshal_pinvoke_cleanup", referenced from:
    37.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    38.   "_IntegratedSubsystemDescriptor_tCC675C388E8A720B9467FCE039B00E7BE7693812_marshal_pinvoke", referenced from:
    39.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    40.   "_XRCameraSubsystemCinfo_t2DEC704C4D0CB1EC17BB8521B3358EE08C878BCC_marshal_pinvoke", referenced from:
    41.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    42.   "_XRCameraSubsystemCinfo_t2DEC704C4D0CB1EC17BB8521B3358EE08C878BCC_marshal_pinvoke_back", referenced from:
    43.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    44.   "_PlaneRemovedEventArgs_t21E9C5879A8317E5F72263ED2235116F609E4C6A_marshal_pinvoke", referenced from:
    45.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    46.   "_XRCameraSubsystemCinfo_t2DEC704C4D0CB1EC17BB8521B3358EE08C878BCC_marshal_pinvoke_cleanup", referenced from:
    47.       _g_Il2CppInteropData in Il2CppInteropDataTable.o
    48.  
    I initially posted my question here , but thought it would be more relevant to post it here. Appreciate any help. Thank you for your work!
     
    AbsAlx likes this.
  31. DirkDenzer

    DirkDenzer

    Joined:
    May 8, 2019
    Posts:
    11
    Not sure if someone mentioned that already but there is a typo in your generated iOS Framework.
    The method UnityFramework.unloadApplication is named unloadApplicaion, it is missing the t.
     
    dabo248, ChrisEtches and ptc-rlopez like this.
  32. shivam_unity411

    shivam_unity411

    Joined:
    Mar 5, 2019
    Posts:
    1
    It is for Objective-C only.How do we get it for Swift?
     
    leeprobert and AbsAlx like this.
  33. mpleasur

    mpleasur

    Joined:
    Jun 12, 2018
    Posts:
    3
    I got to step 5 but when I look at the Unity-IPhone folders in Xcode and go to libraries/plugins/ios/ there is no file called NativeCallProxy.h - is there some place I need to get this from? I only see some unity files here but nothing called nativecallproxy.h

    Here is a photo of what I see:

    any help on what part I am missing here would be great!
     

    Attached Files:

    grizzlynt likes this.
  34. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    @DirkDenzer, @mpleasur
    At bare minimum Unity as a Library for iOS generates Xcode project with framework and app/launcher with main function (observe MainApp/main.mm) to run it. NativeProxyCall and files in Assets/Plugins/* are created specifically for this example to showcase how communication between Unity and Native app might look like and they wont be in any other Unity project.

    Based on your project specifics you will need develop something that suits your needs. Blocks for that would be: UnityFramework.h, https://docs.unity3d.com/Manual/PluginsForIOS.html, UnitySendMessage, etc..
     
    Last edited: Jul 26, 2019
  35. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    We receiving requests/feedback on Swift integration and its something to be considered in next iteration over Unity as a Library (no ETD).
    Someone was referencing Unity to Swift integration repo for 2018, maybe Swift part is still applicable to 2019.3
     
    Last edited: Jul 26, 2019
    khaled24 and kiles like this.
  36. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    There should be no extra steps for Vuforia to work in embedding scenario, what issue you are facing ?
     
  37. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    After generation of Xcode project take a look at editor console if there are issues related to ARKit/Xcode target names then it is known issue for ARKit 2.0.8. Try upgrade to version 3.*
     
  38. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    Thanks for spotting this up.
     
    DirkDenzer likes this.
  39. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    It is something you will need to implement, there are many ways how you can do it:
    One way is to make a call from C# to your native code( and native will do the job)
    - C# to native (now you in UnityFramework)
    - UnityFramework to your Native app
    something like NativeCallProxy as in this example
    or NSNotification
     
  40. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    Hi, good questions.

    1. It is hard one, there were different kind of constraints and objectives to consider, i think important one was to keep iOS Player player in one single form: framework. That works the same in different scenarios. In usual use case use framework though tiny launcher and in integration scenario it is the exactly the same framework with custom launcher.

    2&3 As mentioned ODR is one of the reasons but also there are many plugins and source code around where data path is hard-coded and expected to be in main bundle. So by default data expected in main but there is a API to specify path based on specific needs of a project.

    Also worth to mention it is first iteration of Unity as a Library and feedback like this with real uses cases and suggestions will shape the feature over next iterations(no ETA)
     
  41. mpleasur

    mpleasur

    Joined:
    Jun 12, 2018
    Posts:
    3
    My error seems similar to this - but I dont think it is exactly the same.

    My error is:
    Thread 1: signal SIGABRT

    and is with this line:
    surface->drawableProxyRT = [surface->device newTextureWithDescriptor: txDesc];

    This is the entire block of code it is in:

    @Synchronized(surface->layer)

    {

    OSAtomicCompareAndSwap32Barrier(0, 0, &surface->bufferCompleted);

    OSAtomicCompareAndSwap32Barrier(0, 0, &surface->bufferSwap);



    for (int i = 0; i < kUnityNumOffscreenSurfaces; i++)

    {

    // Allocating a proxy texture is cheap until it's being rendered to and the GPU driver does allocation

    surface->drawableProxyRT = [surface->device newTextureWithDescriptor: txDesc];

    }

    }


    in the metalhelper.mm file.

    I keep getting this error when trying to make any changes to the unity project. The error has happened a few times in different unity tests and it is always the same error.
    Any help would be great.

    Here
     
    AbsAlx likes this.
  42. mpleasur

    mpleasur

    Joined:
    Jun 12, 2018
    Posts:
    3

    I have begun building my own way of communication between the unity and native app - but I wanted to know is it possible to create buttons for the view controller that only appear in the end of the unity game - ie in the last scene of your game?
     
  43. gerdich

    gerdich

    Joined:
    Feb 19, 2016
    Posts:
    10
    The best would be if the app could be displayed and interacted from Firemonkey (Delphi) on a Canvas :...
     
  44. PavelLU

    PavelLU

    Unity Technologies

    Joined:
    Feb 23, 2017
    Posts:
    107
    yes, one easy way of doing is to have a callback at the end of unity game to native, that will create or makes visible buttons that will be added to unity view controller similarly as it is done in this example.
     
  45. sahadha777

    sahadha777

    Joined:
    Jul 14, 2018
    Posts:
    15
    How to do it for swift
     
    AbsAlx likes this.
  46. CodingPanda619

    CodingPanda619

    Joined:
    Nov 17, 2017
    Posts:
    1
    hi, Application.Unload() doesnt work for ios and when we switch to ios view controller after loading unity scene, how does memory be released for the framework , is their a workaround for unloading unity framework and loading again when required to handle memory issues ?
     
    lawinww likes this.
  47. lawinww

    lawinww

    Joined:
    Mar 20, 2019
    Posts:
    3
    unity_framework.unloadApplication(true) got crash in UnityRepaint().
    And unity_framework.unloadApplication(false) got crash when I try to relaunch the game.
     
  48. Querke

    Querke

    Joined:
    Feb 21, 2013
    Posts:
    54
    Crashing when unloading through unity framework.
    Trying to call unityframework UnloadApplication(tried both true and false). And getting error code:
    ("GraspFinalTest" is the name of the iOS application)

    DEBUG LOG: unloading unity from NativeCallsProxy.h. Message: red

    Setting up 1 worker threads for Enlighten.
    Thread -> id: 16fc1f000 -> priority: 1
    2019-08-20 10:30:02.727453+0200 GraspFinalTest[328:35902] Task <967CA1F7-14E2-47F1-A85C-E792FB21D7DD>.<1> finished with error - code: -999
    2019-08-20 10:30:02.727966+0200 GraspFinalTest[328:35971] Task <967CA1F7-14E2-47F1-A85C-E792FB21D7DD>.<1> load failed with error Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://config.uca.cloud.unity3d.com/, NSErrorFailingURLKey=https://config.uca.cloud.unity3d.com/, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalUploadTask <967CA1F7-14E2-47F1-A85C-E792FB21D7DD>.<1>"
    ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <967CA1F7-14E2-47F1-A85C-E792FB21D7DD>.<1>, NSLocalizedDescription=cancelled} [-999]
    2019-08-20 10:30:02.731281+0200 GraspFinalTest[328:35970] [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C1.1:2][0x14dec3b30] get output frames failed, state 8196
    2019-08-20 10:30:02.731857+0200 GraspFinalTest[328:35970] [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C1.1:2][0x14dec3b30] get output frames failed, state 8196
    2019-08-20 10:30:02.733650+0200 GraspFinalTest[328:35970] TIC Read Status [1:0x0]: 1:57
    2019-08-20 10:30:02.734007+0200 GraspFinalTest[328:35970] TIC Read Status [1:0x0]: 1:57
    UnityFramework was compiled with optimization - stepping may behave oddly; variables may not be available.
    (lldb)


    EDIT: Also, I am calling the unloadApplicaiton function from swift. But shouldn't be a problem with that.
     
  49. RichardEng

    RichardEng

    Joined:
    Jun 14, 2013
    Posts:
    4
    Just to confirm, is the expected behaviour that this will _only_ work on a device and not in simulator? Is there any way of making it work with simulator? Thank you.
     
  50. Querke

    Querke

    Joined:
    Feb 21, 2013
    Posts:
    54
    How I did Swift integration

    EDIT: Updated solution can be found here: https://forum.unity.com/threads/int...-in-native-ios-app.685219/page-2#post-5038628


    Ok, so I think I got a swift integration working (it's working on my end at least :D). Here you can init and show embedded unity. And send messages to C# scripts. (unloading unity doesn't work yet, and I am too inexperienced as to understand why).

    Please understand that I have never ever touched iOS development, nor any other language than Java and C#. So I am not sure if this is a good way to do it. Use at your own risk :D

    How to use it
    Create a swift project and workspace:
    Follow the guide in the original post as normal. But instead, make a swift project. And import that swift project into the workspace. Remember to follow the steps with adding the unity framework to the xcode project, and setting data folder to be a part of Unity Framework.

    Import the UnityEmbeddedSwift.swift file
    Just drag and drop the file into the native swift iOS xcode project.
    Warning: I had issues where the xcode project didn't find the UnityFramework. I solved it by building the UnityFramework first, then clean the project (Command + shift + K).

    Set launch options:
    In my AppDelegate.swift file, under the "func application" method, I call UnityEmbeddedSwift.setLaunchOptions(launchOptions)

    class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    UnityEmbeddedSwift.setLaunchOptions(launchOptions)
    return true
    }
    (...)
    }


    Then I created some buttons that calls the different methods to launch Unity and send message to it:
    This is done in my ViewController

    @IBAction func initUnityBtn(_ sender: UIButton) {
    let instance : UnityEmbeddedSwift = UnityEmbeddedSwift()
    instance.initUnity()
    }

    //Setting unity message, this is called when unity is initialized or shown.
    //You can also call sendUnityMessage() to send it right away (unity needs to be initialized first)
    @IBAction func setUnityMsgBtn(_ sender: UIButton) {
    UnityEmbeddedSwift.setUnityMessage("Some GameObject name", methodName: "SomeCSharpMethodName", message: "string parameter")
    }


    Here is my Swift integration file:
    Code (Boo):
    1. //
    2. //  Created by Simon Tysland on 19/08/2019.
    3. //  Copyright © 2019 Simon Tysland. All rights reserved.
    4. //
    5.  
    6. import Foundation
    7. import UnityFramework
    8.  
    9. class UnityEmbeddedSwift: UIResponder, UIApplicationDelegate, UnityFrameworkListener {
    10.  
    11.     private var ufw : UnityFramework!
    12.     private static var launchOptions : [UIApplication.LaunchOptionsKey: Any]?
    13.     private static var unityMessageObjectName : String = "default value"
    14.     private static var unityMessageMethodName : String = "default value"
    15.     private static var unityMessageBody : String = "default value"
    16.     private static var unityMessagesQueued : Bool = false
    17.  
    18.     func unityIsInitialized() -> Bool {
    19.         return ufw != nil && (ufw.appController() != nil)
    20.     }
    21.  
    22.     static func setLaunchOptions(_ launchOpts : [UIApplication.LaunchOptionsKey: Any]?){
    23.         UnityEmbeddedSwift.launchOptions = launchOpts
    24.     }
    25.  
    26.     static func setUnityMessage(_ objectName : String, methodName : String, message : String) {
    27.         UnityEmbeddedSwift.unityMessageObjectName = objectName
    28.         UnityEmbeddedSwift.unityMessageMethodName = methodName
    29.         UnityEmbeddedSwift.unityMessageBody = message
    30.         UnityEmbeddedSwift.unityMessagesQueued = true
    31.     }
    32.  
    33.     func sendUnityMessage() {
    34.         if(UnityEmbeddedSwift.unityMessagesQueued && unityIsInitialized())
    35.         {
    36.             ufw.sendMessageToGO(withName: UnityEmbeddedSwift.unityMessageObjectName, functionName: UnityEmbeddedSwift.unityMessageMethodName, message: UnityEmbeddedSwift.unityMessageBody)
    37.             UnityEmbeddedSwift.unityMessagesQueued = false
    38.         }
    39.     }
    40.  
    41.     func showMainView() {
    42.         if unityIsInitialized() {
    43.             ufw.showUnityWindow()
    44.             sendUnityMessage()
    45.         }
    46.     }
    47.  
    48.     func initUnity() {
    49.         if unityIsInitialized() {
    50.             showMainView()
    51.             return
    52.         }
    53.  
    54.         self.ufw = UnityFrameworkLoad()!
    55.         ufw.setDataBundleId("com.unity3d.framework")
    56.         ufw.register(self)
    57.  
    58.         ufw.runEmbedded(withArgc: CommandLine.argc, argv: CommandLine.unsafeArgv, appLaunchOpts: UnityEmbeddedSwift.launchOptions)
    59.  
    60.         sendUnityMessage()
    61.     }
    62.  
    63.     func unloadUnity() {
    64.         if unityIsInitialized() {
    65.             ufw.unloadApplication(true)
    66.             ufw = nil
    67.         }
    68.     }
    69.  
    70.     func UnityFrameworkLoad() -> UnityFramework? {
    71.         let bundlePath: String = Bundle.main.bundlePath + "/Frameworks/UnityFramework.framework"
    72.  
    73.         let bundle = Bundle(path: bundlePath )
    74.         if bundle?.isLoaded == false {
    75.             bundle?.load()
    76.         }
    77.  
    78.         let ufw = bundle?.principalClass?.getInstance()
    79.         if ufw?.appController() == nil {
    80.             // unity is not initialized
    81.             //            ufw?.executeHeader = &mh_execute_header
    82.      
    83.             let machineHeader = UnsafeMutablePointer<MachHeader>.allocate(capacity: 1)
    84.             machineHeader.pointee = _mh_execute_header
    85.      
    86.             ufw!.setExecuteHeader(machineHeader)
    87.         }
    88.         return ufw
    89.     }
    90. }
    91.  
    So this means that you do not need to use the mainViewController.mm file provided in the original post (nor a customized Obj-C + header file for that matter), if you are using swift.

    Hope you guys find this useful.
     

    Attached Files:

    Last edited: Oct 7, 2019