如何构build适用于iOS的Unity3d插件
我有一个为iOS构build的非常小的Objective-C库,我想将它导出到Unity。 我理解编写一个csharp包装的基本过程,它将所有的调用整理到本地库,但我完全不知道从哪里开始。 任何人都可以请一步一步解释如何创build一个统一包与我的图书馆,所以我也可以分发给其他开发人员。
Unity3D文档非常简短,并没有解释任何东西。
谢谢。
好吧,在Mac上玩了几天Unity3d后,我终于明白了。 本指南中的所有代码都是假的。 我已经在15分钟左右写完了这些东西,所以不要被错误和错误打扰。
1)打开Unity,创build新项目(文件 – >新build项目)并保存在某个地方
2)项目生成时,它有以下结构:
-
ProjectName/Assets
(这就是你需要的) -
ProjectName/Library
(不知道那里有什么) -
ProjectName/ProjectSettings
(你不关心它) -
ProjectName/ProjectName.sln
(MonoDevelop项目)
3)转到ProjectName/Assets
并创build以下文件夹: Plugins/iOS
,所以最后你会有一个像这样的文件夹结构: ProjectName/Assets/Plugins/iOS
4)将你编译的库(.a)文件和必要的头文件放在ProjectName/Assets/Plugins/iOS
或者把你的库的源代码复制到(.mm,.h,.m等)。 请记住,通常你只能从C#访问C函数,所以你必须以某种方式将你的Objective-C的东西包装成C代码,在我的例子中,所有的Objective-C对象都是以Singleton的forms实现的,很难做一个C型的包装,例如:
CWrapper.h :
extern "C" void MySDKFooBarCFunction();
CWrapper.mm
#import "CWrapper.h" #import "MyObjectiveCLibrary.h" // your actual iOS library header void MySDKFooBarCFunction() { [MyObjectiveCLibrary doSomeStuff]; }
5)然后转到ProjectName/Assets
并为CSharp包装类创build一个文件夹,随便调用它,例如: ProjectName/Assets/MySDK
6)在MySDK文件夹里面创buildMySDK.cs文件,C#wrapper的例子看起来像这样:
using UnityEngine; using System; using System.Runtime.InteropServices; public class MySDK { // import a single C-function from our plugin [DllImport ("__Internal")] private static extern void MySDKFooBarCFunction(); // wrap imported C-function to C# method public static void FooBarCFunction() { // it won't work in Editor, so don't run it there if(Application.platform != RuntimePlatform.OSXEditor) { MySDKFooBarCFunction(); } } }
7)创build一个shell脚本,将这些东西打包到.unitypackage
然后把它放到你的项目文件夹(不在里面)。 根据需要调整脚本中的EXPORT_PATH
和PROJECT_PATH
variables。
#!/bin/sh WORKDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" UNITY_BIN="/Applications/Unity/Unity.app/Contents/MacOS/Unity" EXPORT_PATH="${WORKDIR}/ProjectName.unitypackage" PROJECT_PATH="${WORKDIR}/ProjectName" ASSETS_PATH="Assets" $UNITY_BIN -batchmode -quit \ -logFile export.log \ -projectPath $PROJECT_PATH \ -exportPackage $ASSETS_PATH $EXPORT_PATH
8)运行创build的bash脚本来构build你的包。 当您通过Unity编辑器中的文件 – >构build设置生成资源时,Assets中的所有内容都将包含在Unity项目的XCode项目中。 您可以使用生成的包将代码分发给其他开发人员,这样他们可以通过双击包文件简单地将库包含到他们的Unity项目中。
当你运行这个脚本时,不要忘记closuresUnity Editor,否则可能无法构build一个包。
如果您遇到一些问题并且程序包不显示,则此脚本始终将日志打印到export.log
只有当你想为你的库创build一个Demo团队项目时,下一步才有意义(至less对于testing是有好处的)
9)你可以把创build的Unity项目(ProjectName.unity)放到Assets/MySDKDemo
这样你的Assets/MySDKDemo
就有了一个演示。
10)在Assets/MySDKDemo/MySDKDemo.cs
中为Demo Unity3d场景创build一个简单的脚本,例如:
using UnityEngine; using System; using System.Collections; public class MySDKDemo : MonoBehaviour { private GUIStyle labelStyle = new GUIStyle(); private float centerX = Screen.width / 2; // Use this for initialization void Start () { labelStyle.fontSize = 24; labelStyle.normal.textColor = Color.black; labelStyle.alignment = TextAnchor.MiddleCenter; } void OnGUI () { GUI.Label(new Rect(centerX - 200, 20, 400, 35), "MySDK Demo", labelStyle); if (GUI.Button(new Rect(centerX - 75, 80, 150, 35), "DoStuff")) { MySDK.FooBarCFunction(); } } }
11)转到Unity编辑器。 在Unity Editor的左边栏中find“Main Camera”,选中它并在Inspector面板的底部(右侧边栏)点击AddComponent,selectScripts – > MySDKDemo脚本
12)构buildXCode项目并在设备上运行。
几个笔记
1)插件在Unity编辑器中不起作用,仅仅是因为它们不是实时编译的,不知道,但可能直到你在插件中使用C#,C#的东西可能被连接起来,并在编辑器环境中工作。
2)本文不包括本地<>托pipe代码之间的编组或数据/内存pipe理,因为它有很好的文档logging。
与Native Libraries @ Mono项目互操作
3)从C#到C的callback可以通过使用C#委托传递,在C端使用标准函数声明,在C#端声明委托具有相同的签名。 看起来,布尔值,整数和string(C:char *)是完美的编组(我不谈论内存pipe理策略,谁负责释放内存或返回值策略)。
然而,由于平台的限制,它不能在iOS上工作,但是C#到C的callback仍然可以使用MonoPInvokeCallbackAttribute来实现,这个主题是有用的链接:
- 反向callback@ Xamarin文档
- MonoPInvokeCallbackAttribute示例@ Xamarin论坛
实际上,在Unity 4中已经实现了AOT.MonoPInvokeCallbackAttribute
,它仅限于可以传递给非托pipe代码的静态委托,但仍比没有好。
4)有一种方法可以使用UnityGetGLViewController
函数获得Unity RootViewController。 只需在你的实现文件中声明这个函数,即:
extern UIViewController *UnityGetGLViewController();
当你需要访问RootViewController时,使用UnityGetGLViewController()
。
5)在细节上有更多的魔法和丑陋的东西,保持你的C接口尽可能简单,否则编组可能成为你的噩梦,也要记住托pipe到非托pipe通常是昂贵的。
6)你肯定在你的本地代码中使用了一些框架,你不希望链接器出现问题。 例如,如果您在库中使用Keychain,则需要将Security.framework包含到Xcode项目中。
我build议尝试XUPorter ,它帮助Unity将任何附加的依赖项集成到Xcode项目中。
祝你好运!
我已经写了一篇关于如何为iOS创buildiOS插件的文章。 你可以在这里检查。 希望能帮助到你。 谢谢。