首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何为iOS构建Unity3d插件

如何为iOS构建Unity3d插件
EN

Stack Overflow用户
提问于 2013-02-12 22:18:06
回答 1查看 27.3K关注 0票数 68

我有一个为iOS构建的非常小的Objective-C库,我想把它导出到Unity。我了解编写将所有调用编组到本机库的csharp包装器的基本过程,但我完全不知道从哪里开始。有没有人可以一步一步地解释如何用我的库创建一个unity包,这样我也可以将它分发给其他开发人员。

Unity3d文档非常简短,没有解释任何内容。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-15 06:13:28

好了,在Mac上玩了几天Unity3d之后,我终于弄明白了。本指南中的所有代码都是虚拟的。我在15分钟左右就写好了这篇文章,所以不要被错误和错别字所困扰。

1)打开Unity,创建新项目(文件->新项目)并保存到某个地方

2)工程生成时,结构如下:

  • ProjectName/Assets (That what you need)
  • ProjectName/Library )(别管什么是there)
  • ProjectName/ProjectSettings (你不关心it)
  • ProjectName/ProjectName.sln (MonoDevelop项目)

3)转到ProjectName/Assets并创建以下文件夹:Plugins/iOS,因此最终您将拥有如下的文件夹结构:ProjectName/Assets/Plugins/iOS

4)将您的编译库(.a)文件和必要的头文件放在ProjectName/Assets/Plugins/iOS中,或者将您的库的源代码复制到那里(.mm、.h、.m等)。记住,通常你只能从C#访问C-functions,所以你必须以某种方式用C代码包装你的Objective-C东西,在我的例子中,所有的Objective-C对象都是以单例的形式实现的,所以做一个C风格的包装器并不难,例如:

CWrapper.h

代码语言:javascript
复制
extern "C" void MySDKFooBarCFunction();

CWrapper.mm

代码语言:javascript
复制
#import "CWrapper.h"
#import "MyObjectiveCLibrary.h" // your actual iOS library header

void MySDKFooBarCFunction() {
    [MyObjectiveCLibrary doSomeStuff];
}

5)然后转到ProjectName/Assets,为CSharp包装器类创建一个文件夹,想怎么叫都行,例如:ProjectName/Assets/MySDK

6)在MySDK文件夹中创建MySDK.cs文件,C#包装器的虚拟示例如下所示:

代码语言:javascript
复制
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)创建一个外壳脚本,将这些内容打包到.unitypackage中,并将其放在项目文件夹旁边(而不是内部)。根据需要调整脚本中的EXPORT_PATHPROJECT_PATH变量。

代码语言:javascript
复制
#!/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)运行创建的bash脚本来构建包。当您通过Unity编辑器中的文件->构建设置生成Unity项目时,所有来自资源的东西都将包含在Unity项目的XCode项目中。您可以使用生成的包将您的代码分发给其他开发人员,这样他们就可以通过双击包文件将您的库包含到他们的Unity项目中。

运行此脚本时,不要忘记关闭Unity Editor,否则它可能无法构建包。

如果您有一些问题并且软件包没有显示,此脚本将始终将日志打印到export.log

只有当你想为你的库创建一个Demo unity项目(至少对测试很好)时,下一步才有意义

9)你可以将创建的Unity项目(ProjectName.unity)放到Assets/MySDKDemo中,这样你的包中就有了一个演示。

10)在Assets/MySDKDemo/MySDKDemo.cs上为您的演示Unity3d场景创建一个简单的脚本,例如:

代码语言:javascript
复制
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 Editor。在Unity编辑器的左边栏中找到"Main Camera“,选择它,然后在Inspector面板(右边栏)的底部点击AddComponent,选择Scripts -> MySDKDemo script

12)构建XCode项目并在设备上运行。

少笔记

1)插件不能在Unity Editor中工作,很简单,因为它们不是实时编译的,嗯,不确定,但可能直到你在插件中使用C#,C#的东西可能会立即链接并在编辑器环境中工作。

2)这篇文章不涉及编组,或者本机<->托管代码之间的数据/内存管理,因为它有很好的文档记录。

Interop with Native Libraries @ Mono project

3)从C#到C的回调可以使用C#委托传递,在C端你使用标准函数声明,在C#端你用相同的签名声明委托。似乎布尔值、整数和字符串(C: char*)被完美地编组(我不会讨论内存管理策略以及谁负责释放内存或返回值策略)。

然而,由于平台的限制,它不能在iOS构建上工作,但是C#到C的回调仍然可以使用MonoPInvokeCallbackAttribute实现,这是关于这个主题的有用链接:

实际上在Unity4中已经实现了AOT.MonoPInvokeCallbackAttribute,它仅限于可以传递给非托管代码的静态委托,但仍然比什么都没有好。

4)有一种使用UnityGetGLViewController函数获取Unity RootViewController的方法。只需在您的实现文件中声明此函数,即:

代码语言:javascript
复制
extern UIViewController *UnityGetGLViewController();

无论何时需要访问RootViewController,都可以使用UnityGetGLViewController()

5)细节中有更多的神奇和丑陋的东西,保持你的C接口尽可能简单,否则编组可能会成为你的噩梦,并记住托管到非托管通常是昂贵的。

6)你肯定在你的原生代码中使用了一些框架,并且你不想要链接器问题。例如,如果您在库中使用Keychain,那么您需要将Security.framework包含到Xcode项目中。

我建议尝试一下XUPorter,它可以帮助Unity将任何额外的依赖项集成到Xcode项目中。

祝好运!

票数 89
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14834626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档