hybcoder1992
侠客
侠客
  • UID45
  • 粉丝0
  • 关注0
  • 发帖数2
阅读:4151回复:5

unity和ios交互-实现扫二维码功能

楼主#
更多 发布于:2015-08-01 17:44

为了介绍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();    
}
@end
3、做过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];
}
@end
4、还要修改下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,你们到时候自己重新导进去吧。
附件名称/大小 下载次数 最后更新
0801demo.zip (36KB)  25 2015-08-01 17:43

最新喜欢:

popleipoplei

欢迎分享

归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
沙发#
发布于:2015-08-01 22:45
AR学院(www.arvrschool.com),从这里感触未来!
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
板凳#
发布于:2015-08-01 22:46
下次可以发云盘
AR学院(www.arvrschool.com),从这里感触未来!
Leo
Leo
骑士
骑士
  • UID8
  • 粉丝1
  • 关注2
  • 发帖数22
  • 社区居民
地板#
发布于:2015-08-03 11:31
wang
贫民
贫民
  • UID2488
  • 粉丝0
  • 关注0
  • 发帖数2
4楼#
发布于:2016-08-25 17:59
傻逼  写的啥啊
wang
贫民
贫民
  • UID2488
  • 粉丝0
  • 关注0
  • 发帖数2
5楼#
发布于:2016-08-25 18:00
脚本挂的也是没谁了  你还是洗洗睡吧  以后别上传了
游客

返回顶部