Unity3d的ios插件开发
戴维营教育原创文章,转载请注明出处。我们的梦想是做最好的iOS开发培训!
Unity3D是一个非常强大的跨平台游戏引擎,但还是也免不了需要访问平台本身的一些功能。Unity3D并没有将平台方方面面都创建对应的API,尤其是比较新的一些功能。这时需要我们自己编写本地插件来解决,本文主要介绍如何开发Unity3D的iOS本地相册插件GlobalBrowser(能够自动扫描Documents目录,并且使用照片墙展示,其中展示功能使用了一个Objective-C的开源控件MWPhotoBrowser)。
准备工作
本文使用Unity 5和Xcode 6.2进行开发,目前只有Unity 4.6和Unity 5支持arm64,并且只有Unity 5支持在插件中使用子目录。我们有三种使用Objective-C代码的方式:源码、静态库(.a)和框架(iOS 8),这一次我们选择纯源码的方式。
本地代码编写
1、新建iOS的项目PhotoBrowser,在项目目录下创建Library文件夹。
2、将MWPhotoBrowser以及所使用的其它开源代码复制到Library,并添加到Xcode项目中。
3、创建GlobalBrowser目录,然后创建DVIGlobalBrowser类。我们在这个类中实现图片浏览插件的本地代码。为了简单起见,我们只实现了几个类方法,然后使用一个静态变量保存对象。
#import <Foundation/Foundation.h>
@interface DVIGlobalBrowser : NSObject
+ (void)show;
+ (void)dismiss;
@end
/////////////实现代码////////////////////////
#import "DVIGlobalBrowser.h"
#import <UIKit/UIKit.h>
#import "MWPhotoBrowser.h"
#import "MWPhoto.h"
static DVIGlobalBrowser *sharedInstance = nil;
@interface DVIGlobalBrowser () <MWPhotoBrowserDelegate>
{
NSArray *_photosArray;
NSString *_photoDir;
}
@property (nonatomic, strong) MWPhotoBrowser *photoBrowser;
@end
@implementation DVIGlobalBrowser
+ (void)initialize {
sharedInstance = [[DVIGlobalBrowser alloc] init];
sharedInstance.photoBrowser = [[MWPhotoBrowser alloc] initWithDelegate:sharedInstance];
sharedInstance.photoBrowser.displayActionButton = YES;
sharedInstance.photoBrowser.displayNavArrows = YES;
sharedInstance.photoBrowser.displaySelectionButtons = NO;
sharedInstance.photoBrowser.alwaysShowControls = NO;
sharedInstance.photoBrowser.zoomPhotosToFill = YES;
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
sharedInstance.photoBrowser.wantsFullScreenLayout = YES;
#endif
sharedInstance.photoBrowser.enableGrid = YES;
sharedInstance.photoBrowser.startOnGrid = YES;
sharedInstance.photoBrowser.enableSwipeToDismiss = YES;
// [sharedInstance.photoBrowser setCurrentPhotoIndex:0];
}
+ (void)show {
[sharedInstance loadPhotos];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:sharedInstance.photoBrowser];
nc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
UIWindow *appWin = [UIApplication sharedApplication].keyWindow;
[appWin.rootViewController presentViewController:nc animated:YES completion:nil];
[sharedInstance.photoBrowser reloadData];
}
+ (void)dismiss {
[sharedInstance.photoBrowser dismissViewControllerAnimated:YES completion:nil];
}
- (void)loadPhotos {
if (_photoDir == nil) {
_photoDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
}
NSArray *array = [[NSFileManager defaultManager] subpathsAtPath:_photoDir];
_photosArray = array;
}
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photosArray.count;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
NSString *filename = _photosArray[index];
NSString *path = [_photoDir stringByAppendingPathComponent:filename];
MWPhoto *photo = [MWPhoto photoWithURL:[NSURL fileURLWithPath:path]];
return photo;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index {
NSString *filename = _photosArray[index];
NSString *path = [_photoDir stringByAppendingPathComponent:filename];
MWPhoto *photo = [MWPhoto photoWithURL:[NSURL fileURLWithPath:path]];
return photo;}
@end
4、由于Unity3D那边只支持C/C++的函数,我们需要再进一步封装上面的代码,并且用extern "C"
导出必要的函数。
//.h文件中
extern "C" void showPhotoBrowser(void);
//.m文件中
void showPhotoBrowser(void) {
[DVIGlobalBrowser show];
}
void dismissPhotoBrowser(void) {
[DVIGlobalBrowser dismiss];
}
5、在iOS项目中测试DVIGlobalBrowser
。
接口代码编写
在Unity3d中调用Objective-C代码,最终要的是编写C#的接口。在GlobalBrowser文件夹中创建C#接口文件PhotoBrowser.cs。
public class PhotoBrowser {
//引入C语言中的函数
[DllImport ("__Internal")]
private static extern void showPhotoBrowser();
//暴露给C#的函数
public static void showPhotoBrowserEx() {
//平台判断
if (Application.platform == RuntimePlatform.IPhonePlayer) {
showPhotoBrowser();
}
}
}
测试项目
在Unity3d的一个场景中加入按钮。没有使用过截屏功能的,需要注意存储路径。
using UnityEngine;
using System.Collections;
public class MyFile : MonoBehaviour {
// Use this for initialization
void Start () {
// print ("Start...");
}
// Update is called once per frame
void Update () {
// print ("Update...");
}
void OnGUI () {
// print ("onGUI...");
//创建按钮,用来显示相册
if (GUI.Button (new Rect (100, 100, 100, 100), "Button")) {
PhotoBrowser.showPhotoBrowserEx();
}
//创建截屏按钮
if (GUI.Button(new Rect(100, 220, 100, 100), "Save")) {
var savePath = Application.persistentDataPath + "/" + (Random.value * 100) + "image.png";
print (savePath + "<--->Capture");
//截屏并保存图片到Documents目录
Application.CaptureScreenshot((Random.value * 100) + "image.png");
}
}
}
本文档由长沙戴维营教育整理。