Подтвердить что ты не робот

Как создать плагин Unity3d для iOS

У меня очень маленькая библиотека Objective-C, созданная для iOS, и я хочу экспортировать ее в Unity. Я понимаю основной процесс написания обертки csharp, которая марширует все вызовы в родную библиотеку, но я совершенно не знаю, с чего начать. Может кто-нибудь, пожалуйста, объясните шаг за шагом, как создать единый пакет с моей библиотекой, чтобы я мог также распространять его для других разработчиков.

Документация Unity3d довольно кратка и ничего не объясняет.

Спасибо.

4b9b3361

Ответ 1

Хорошо, после нескольких дней работы с Unity3d на Mac я, наконец, понял это. Весь код в этом руководстве является фиктивным. Я написал этот материал за 15 минут или около того, поэтому не надо беспокоиться о ошибках и опечатках.

1) Откройте Unity, создайте новый проект (Файл → Новый проект) и сохраните его где-нибудь

2) Когда проект сгенерирован, он имеет следующую структуру:

  • ProjectName/Assets (Что вам нужно)
  • ProjectName/Library (Nevermind, что там)
  • ProjectName/ProjectSettings (вас это не волнует)
  • ProjectName/ProjectName.sln (проект MonoDevelop)

3) Перейдите к ProjectName/Assets и создайте следующие папки: Plugins/iOS, поэтому в конце вы получите такую ​​структуру папок, как это: ProjectName/Assets/Plugins/iOS

4) Поместите файл скомпилированной библиотеки (.a) и необходимые заголовки внутри ProjectName/Assets/Plugins/iOS или скопируйте исходный код своей библиотеки там (.mm,.h,.m и т.д.). Помните, как правило, вы можете получить доступ только к C-функциям из С#, поэтому вам придется обернуть ваш материал Objective-C в C-коде как-то, в моем случае все объекты Objective-C были реализованы в форме Singleton, так что это wasn ' t трудно создать оболочку 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 (es), вызовите ее, как хотите, например: ProjectName/Assets/MySDK

6) Внутри папки MySDK создайте файл MySDK.cs, фиктивный пример оболочки С# будет выглядеть следующим образом:

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) Создайте оболочку script, чтобы упаковать этот материал в .unitypackage и поместите его рядом с папкой проекта (не внутри). Настройте EXPORT_PATH и PROJECT_PATH переменные в script для ваших нужд.

#!/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 script, чтобы получить сборку вашего пакета. Все материалы из Assets будут включены в проект XCode для вашего проекта Unity при его создании через File → Build Settings в Unity Editor. Вы можете использовать сгенерированный пакет для распространения кода другим разработчикам, чтобы они могли просто включить вашу библиотеку в свои проекты Unity, дважды щелкнув файл пакета.

Не забудьте выключить Unity Editor при запуске этого script, иначе он может не скомпоновать пакет.

Если у вас есть какие-то проблемы, и пакет не отображается, этот script всегда печатает журнал для export.log

Следующие шаги имеют смысл только в том случае, если вы хотите создать демонстрационный проект для вашей библиотеки (желательно для тестирования как минимум)

9) Вы можете поместить созданный проект Unity (ProjectName.unity) в Assets/MySDKDemo, чтобы у вас была демонстрация внутри вашего пакета.

10) Создайте простой script для сцены Demo Unity3d в Assets/MySDKDemo/MySDKDemo.cs, например:

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, выберите ее и в нижней части панели "Инспектор" (правая боковая панель) нажмите "AddComponent", выберите "Сценарии" → "MySDKDemo" script

12) Создайте проект XCode и запустите его на устройстве.

Несколько заметок

1) Плагины не работают в редакторе Unity, просто потому, что они не скомпилированы в режиме реального времени, ну, не уверен, но, вероятно, до тех пор, пока вы не используете С# в своих плагинах, возможно, С# -материал становится связанным и работает Среда редактора.

2) Это сообщение не распространяется на маршалинг или управление данными/памятью между встроенным управляемым кодом, поскольку он очень хорошо документирован.

Взаимодействие с Native Libraries @Mono project

3) Обратные вызовы с С# на C могут передаваться с использованием делегатов С#, на стороне C вы используете объявления стандартных функций, на стороне С# вы объявляете делегатов с одной и той же сигнатурой. Кажется, что логические переменные, целые числа и строки (C: char *) безупречно сортируются (я не говорю о политике управления памятью и кто ответственен за выпуск политики памяти или возврата значений).

Однако он не будет работать на сборках iOS из-за коробки из-за ограничений платформы, но обратные вызовы С# -to-C все еще могут быть реализованы с использованием MonoPInvokeCallbackAttribute, полезные ссылки по этой теме:

На самом деле в Unity 4 там AOT.MonoPInvokeCallbackAttribute уже реализован, он ограничен статическими делегатами, которые могут быть переданы неуправляемому коду, но все же лучше, чем ничего.

4) Есть способ получить Unity RootViewController с помощью функции UnityGetGLViewController. Просто объявите эту функцию в вашем файле реализации, то есть:

extern UIViewController *UnityGetGLViewController();

И используйте UnityGetGLViewController() всякий раз, когда вам нужно получить доступ к RootViewController.

5) В деталях гораздо больше волшебства и уродства, держите свои C-интерфейсы настолько простыми, насколько это возможно, иначе маршаллинг может стать вашим кошмаром, а также иметь в виду, что управляемый неуправляемый, как правило, дорогой.

6) Вы определенно используете некоторые фреймворки в своем родном коде, и вам не нужны проблемы с компоновщиками. Например, если вы используете Keychain в своей библиотеке, тогда вам нужно включить Security.framework в проект Xcode.

Я предлагаю попробовать XUPorter, он помогает Unity интегрировать любые дополнительные зависимости в проект Xcode.

Удачи!

Ответ 2

Я написал сообщение о том, как создать плагин iOS для единства. Вы можете проверить это здесь. Надеюсь, поможет. Спасибо.