Избранное Все заметки GitHub icon Мой Github Обо мне

Избранное

Позднее Ctrl + ↑

Unity iOS plugin

Так как тема мобильной разработки на Unity для меня сейчас актуальна, то продолжу про создание плагинов. Как сделать свой плагин для iOS? Что можно делать с помощью нативных плагинов? Например, показать стандартный ActionSheet или отобразить HTML, или синхронизироваться с iCloud, или получить доступ к галереи картинок опять же... Чтобы сделать простой плагин и xCode не обязателен, на самом деле.

Для примера, сделаем плагин который отображает браузер и загружает какую-нибудь страницу внутри Unity приложения. Плагин будет состоять всего из одного файла, с расширением .mm. В документации есть список форматов и описание сборки под iOS.

Для начала, объявим главный контроллер Unity приложения:

extern UIViewController *UnityGetGLViewController();

Для примера будет достаточно трех функций: показа браузера, загрузки страницы, скрытия браузера.

- (void)showBrowser {
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, screenRect.size.width, screenRect.size.height)];
    [UnityGetGLViewController().view addSubview:webView];
}

- (void)loadUrl:(NSString *)url {
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
}

- (void)close {
    [webView removeFromSuperview];
    webView = NULL;
}

Функция showBrowser добавляет браузер на главный экран, растягивая по высоте и ширине. При желании, в функцию можно передавать отступы, чтобы показывать браузер там где нужно.

Ну и последнее, интерфейс доступа на C:

static Browser *browser = NULL;

extern "C" {
    
    void browserLaunch () {
        if (browser == NULL)
            browser = [[Browser alloc] init];
        [browser showBrowser];
    }
    
    void browserLoadUrl (const char* url) {
        [browser loadUrl:[NSString stringWithUTF8String:url]];
    }
    
    void browserClose () {
        [browser close];
    }
    
}

Это все, плагин готов! Теперь осталось вызывать эти функции из Unity. По аналогии с Android плагином, делаем класс для браузера. Все функции подключаем через [DllImport («__Internal»)], должно получиться что-то такое:

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class Browser : MonoBehaviour {

	#if UNITY_IPHONE
		[DllImport ("__Internal")]
		private static extern void browserLaunch (int left, int right, int top, int bottom);

		[DllImport ("__Internal")]
		private static extern void browserLoadUrl (string url);

		[DllImport ("__Internal")]
		private static extern void browserClose ();
	#endif 

	// Показываем браузер
	public static void Launch (RectOffset offset) {
		#if UNITY_IPHONE
			browserLaunch (offset.left, offset.right, offset.top, offset.bottom);
		#endif
	}

	// Открыть страницу
	public static void LoadUrl (string url) {
		#if UNITY_IPHONE
			browserLoadUrl (url);
		#endif
	}

	// Убрать браузер
	public static void Close () {
		#if UNITY_IPHONE
			browserClose ();
		#endif
	}
}

Тут нужно уточнить, что браузер будет добавлен на главный экран, поверх всего. Поэтому, нужно правильно высчитать отступы, чтобы все выглядело красиво. В примере значения отступов грубо прописаны в коде, так делать не стоит :)

Исходники на GitHub

2016   ios   plugin   unity

Unity Android plugin

Как часто можно встретить на stackoverflow вопросы, про доступ к галереи картинок, или как получить снимок с камеры, или как показать браузер, или как работать с Play Services... Да что уж, я и сам задавал такие вопросы. А всё потому, что к сожалению, в Unity нет (пока) многих специфичных функций, которые зависят от платформы. Но есть возможность подключать нативные плагины, что очень хорошо. С помощью плагинов, можно организовать любое взаимодействие которое поддерживается платформой.

Раньше, плагины можно было компилировать в JAR файлы, закидывать в папку Assets/Plugins/Android и использовать. В общем-то, так можно делать и сейчас, но это подойдет для самых простых плагинов, не использующих ресурсы, которые нужно сохранять в папку res. А на такие вещи Unity стала ругаться и выдавать сообщение в консоль:

OBSOLETE — Providing Android resources in Assets/Plugins/Android/res is deprecated, please move your resources to an Android Library. See «Building Plugins for Android» section of the Manual.

Короче, надо делать Android Library. Если интересует, как сделать плагин по «старой технологии», могу рассказать, а пока — как надо.

Шаг 1.

Скачиваем Android Studio и Android SDK. Тут особых проблем возникнуть не должно.

Шаг 2.

Создаем новый Android Project. Далее, создаем новый модуль: File → New → New Module → Android Library

Шаг 3.

Скопируем JAR файл с классами Unity в папку libs нового модуля. И добавим в раздел с зависимостями Gradle файла строку с классами Unity. Где искать файл classes.jar можно прочитать в документации.

dependencies {
    provided files('libs/classes.jar')
    ...
}

Шаг 4.

Для примера сделаем плагин который показывает всплывающие сообщения, тосты (Toast). Создадим новый класс Plugin и добавим туда один метод show с параметром message. Не самый удачный пример, потому что не используются ресурсы, но самый простой.

package com.mycompany.toast;

import com.unity3d.player.UnityPlayer;
import android.widget.Toast;

public class Plugin {
	// Показать сообщение
	static void show(final String message) {
		UnityPlayer.currentActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				Toast.makeText(UnityPlayer.currentActivity, message, Toast.LENGTH_SHORT).show();
			}
		});
	}	
}

Шаг 5.

В Android Studio, справа в меню Gradle, ищем название модуля которое задали при создании и далее: Tasks → build → assembleRelease. Модуль скомпилируется в AAR файл, то что и нужно.

Шаг 6.

Копируем AAR плагин в папку Assets/Plugins/Android с Unity проектом. И пишем небольшой интерфейс для вызова функции show.

using UnityEngine;
using System.Collections;

public class Toast : MonoBehaviour {

	// Показываем всплывающее сообщение
	public static void Show (string message) {
		#if UNITY_ANDROID
			using (var plugin = new AndroidJavaClass("com.mycompany.toast.Plugin")) {
				plugin.CallStatic("show", message);
			}
		#endif
	}

Шаг 7.

Закидываем приложение на Android устройство и проверяем. Все должно работать.

Это конечно не самый интересный пример, в следующей заметке напишу как получить изображение с камеры или альбома и использовать его в Unity. Или как отобразить HTML страницу в браузере...

2016   android   plugin   unity