阅读:4786回复:5
unity和ios交互-实现扫二维码功能为了介绍unity和ios之间如何交户,我会实现一个很简单的功能模块,在unity的界面中,点击一个按钮,跳转到用ios实现的扫二维码的功能界面,识别到二维码以后,把识别结果返回到unity的界面,并通过一个label显示出来。 一、unity端的实现 1、unity那边的代码比较简单,首先搭了个界面,场景中有个按钮,按钮下方有个uilabel,摄像机挂了个脚本AppManager,脚本中给按钮添加点击事件。点击事件的具体实现暂时空着,等下补上,btn和result这两个变量是public属性,需要手动拖到脚本上。 using UnityEngine; using System.Collections; public class AppManager : MonoBehaviour { public GameObject btn; public GameObject result; // Use this for initialization void Start () { UIEventListener.Get(btn).onClick+=btnClick; } void btnClick(GameObject btn) { } } 2、然后在unity那边写插件方法,我一般做法还是抽一个单例类出来,所有的插件方法都由它来处理。这个单例类的脚本是PluginTool。需要注意一点是,要引入System.Runtime.InteropServices这个命名空间,不然会报错。 using UnityEngine; using System.Collections; using System.Runtime.InteropServices; public class PluginTool : MonoBehaviour { #if UNITY_IOS [DllImport ("__Internal")] private static extern void _launchScannerView(); #endif private static PluginTool _instance=null; private PluginTool(){} public static PluginTool GetInstance() { if(_instance==null) { _instance=new PluginTool(); } return _instance; } public void launchScannerView() { #if UNITY_IOS _launchScannerView(); #endif } } 3、然后在AppManager脚本的btnClick方法中补上点击事件的处理代码,其实从PluginTool 这个脚本可以看出,_launchScannerView这个方法是由ios端实现的,这个方法的功能就是显示由ios实现的扫二维码的界面。 #if UNITY_IOS PluginTool.GetInstance().launchScannerView(); #endif二、ios端的实现 实现扫二维码的方法有很多,一般都是借助第三方库来完成,例如zxing。Ios7以后官方提供了原生的实现,效率上比第三方的要高得多。在这里我也是使用ios原生来实现扫二维码的功能,首先我会在xcode新建个single view项目,然后百度了一下,看了一下别人的代码,修改了一下变成了自己的东西。 1、首先打开xcode,新建个single view application项目。实现扫码功能的核心代码主要在HYBScanCodeController中完成,它只是一个普通的UIViewController,因为HYBScanCodeController的代码边幅稍长,所以在这里就不全部粘贴出来了,比较重要的代码在这里说一下。 1.1view加载完成后调用自定义方法startReading来开始扫描,特别提醒下,如果导出程序是横屏的,会发现这相机捕捉的画面是调转的,可以再startReading方法中设置_videoPreviewLayer.connection.videoOrientation属性,如横屏状态需要这样设置: _videoPreviewLayer.connection.videoOrientation=AVCaptureVideoOrientationLandscapeRight;1.2扫描二维码,识别到码以后会在AVCaptureMetadataOutputObjectsDelegate的代理方法- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection中把扫描结果打印出来。 #pragma mark - AVCaptureMetadataOutputObjectsDelegate - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { //判断是否有数据 if (metadataObjects != nil && [metadataObjects count] > 0) { AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0]; //判断回传的数据类型 if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) { //回传字符串数据 [self performSelectorOnMainThread:@selector(stopReading:) withObject:[metadataObj stringValue] waitUntilDone:YES]; } } }1.3打印了扫描结果后调用stopReading方法来结束扫描 -(void)stopReading:(NSString* )data{ _isReading=false; [_captureSession stopRunning]; _captureSession = nil; [_scanLayer removeFromSuperlayer]; [_videoPreviewLayer removeFromSuperlayer]; //打印扫描结果 NSLog(@"%@-->",data); }2、好了,现在就需要让unity那边来调用ios的viewcontroller了,我们还需要在xcode新建个用来和unity交互的头文件和源文件,HYBPluginTool.h和HYBPluginTool.mm,HYBPluginTool.h的代码比较简单,只是声明了一个_launchScannerView()方法,这个方法是给unity调用的。 #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "HYBScanCodeController.h" @interface HYBPluginTool : NSObject extern "C" { void _launchScannerView(); } @end3、做过ios开发的都知道,改变viewcontroller可以是替换keywindow的rootviewcontroller属性,那么要解决的问题就是,获取unity导出成xcode项目后的rootviewcontroller,其实unity提供了一个方法来获取rootviewcontroller,这个方法在UnityAppController.mm文件中: extern "C" UIViewController* UnityGetGLViewController() { return GetAppController().rootViewController; }但好像替换rootviewcontroller为普通的viewcontroller有有问题,所以我们可以通过模态窗口的方式把自定义的viewcontroller显示出来。下面是HYBPluginTool.mm文件的代码,其实我学ios也不会很长时间,在下面的代码中,你会看到一个HYBScanCodeController的全局变量instance,因为HYBPluginTool没有用到arc,我怕instance变量在程序结束时没有释放掉,所以就把它autorelease。至于HYBScanCodeController可以使用arc,只需要在xcode里面设置项目属性Build Phases中添加-fobjc-arc即可。 #import "HYBPluginTool.h" @implementation HYBPluginTool //Grab the Unity3D ViewController (UnityGetGLViewController()) #ifdef UNITY_4_0 //Unity4 #import "iPhone_View.h" #else //Unity3.5 extern UIViewController* UnityGetGLViewController(); #endif HYBScanCodeController* instance; void _launchScannerView() { instance=[[[HYBScanCodeController alloc] init] autorelease]; [UnityGetGLViewController() presentViewController:instance animated:YES completion:nil]; } @end4、还要修改下HYBScanCodeController.mm里面的stopReading方法,在最后添加代码,把扫描结果回传到unity端并显示出来,UnitySendMessage方法就是调用unity场景中一个Main Camera对象上绑定的其中一个脚本中的onScannerMessage函数。 if(data!=nil) { [self dismissViewControllerAnimated:YES completion:^{ UnitySendMessage("Main Camera", "onScannerMessage", [data cStringUsingEncoding:NSUTF8StringEncoding]); }]; }5、所以还要在unity的AppManager添加onScannerMessage函数 void onScannerMessage(string result) { resultLabel.GetComponent<UILabel>().text=result; }总结,unity和ios的交互主要就是这呀来实现了,ios的代码文件需要放在unity项目文件下的Asset/Plugins/iOS文件夹中,当导出成xcode项目后,这些ios代码文件会在classes/Libraries组里面。写得不是太好,希望各位大哥体谅,我自己也是在项目中摸索,存在不合理的地方希望各位大哥指出。当然,安卓端也可以使用原生功能通过与unity交互来实现扫二维码功能,以后有时间再详细写给大家。我把项目也打包发上来,但有没有真机测试过。。。但核心的东西都在里面了,希望各位大哥谅解。这里上传的附件大小不能超过2m,因为我用了ngui,为了不超过2m我删了ngui,你们到时候自己重新导进去吧。 |
|
最新喜欢:![]() |
沙发#
发布于:2015-08-01 22:45
![]() |
|
|
板凳#
发布于:2015-08-01 22:46
下次可以发云盘
![]() |
|
|