本来打算使用高通的AR插件来实现,但是高通的官网老是登录不上去,没有办法只有使用EasyAR来实现(手动滑稽)
EasyAR注册以及下载首先,我们现在EasyAR的官网进行注册;
注册完成后,申请授权
不做商业开发用,我们选择个人版就好
应用名称和PaceageName需要和在unity中一致(本文我们只做Android开发,故不用申请IOS的BundleID)
授权密钥复制保存下来,等会儿要用;
申请API KEY
API KEY和API Seret复制下来,等会也要用;
接下来,下载SDK;
传送门:
下载-EasyAR官网https://www.easyar.cn/view/download.html
这里我们找到UnityPlugin 下载就好;
EasyAR导入UnityEasyAR4.4.0的版本导入Unity的方式和往常的import的不太一样,需要在Unity的packageManager中进行操作
载入你刚才下好的包;
Zxing插件下载以及导入插件已上传百度网盘,如有需要,自行提取
链接:https://pan.baidu.com/s/16CuwPVNxO4tSu2IOVEYCQg
提取码:xjza
在unity的Assets文件夹下新建一个 Plugins文件夹,将ZXing插件导入;
选择Android
点击PlayerSetting -> player
进行配置;
JDK以及AndroidSDK的接入配置
JDK不要下载过高版本,我下载的是JDK8
AndroidSDK使用的是7.0的版本
具体的SDK和JDK下载以及配置,这里不做详细介绍,如有需要的朋友,可以参考这篇博客
(31条消息) 2018年Unity结合Android SDK下载安装及配置教程_Sinkiang的博客-CSDN博客_unity 安卓sdkhttps://blog.csdn.net/dxj467822057/article/details/80198165?ops_request_misc=&request_id=&biz_id=102&utm_term=unity%E6%8E%A5%E5%85%A5androidsdk&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-6-80198165.first_rank_v2_pc_rank_v29&spm=1018.2226.3001.4187
场景配置找到Resources文件夹下的EasyAR文件夹中的Setting
填入,我们当时申请的密钥、APIKEY 、APISecret(PS:如果需要使用云识别,就填入ServerAddress和CloudRecognizerAppID,不需要就不用填)
为了实现图片追踪的效果,我们需要在场景中新建如下的Object
以及一个ImageTarget
场景中的Camera 需要设置成单色模式,背景色选择成黑色;
设定需要追踪的图像在Assets文件夹下新建一个StreamingAssets文件夹,将需要追踪的图片放进来;并在ImageTarget的Inspector面板设置好参数;
在场景中新建一个Cube,并将它作为ImageTarget的子物体;
至此,打包成APK包,在手机上测试,已经能够完成,识别图片显示模型,并追踪图片位置;
下面开始添加二维码扫描的功能;
二维码扫描脚本在场景中的ImageTarget下在新建一个Sphere,用来测试根据不同的二维码识别信息显示不同的模型;
新建一个Canvas,在Canvas下新建一个Panel,然后在panel下新建几个Text,用来显示我们的Debug信息;
具体的UI层级可以参考我的,也可以自行组织;
首先,我们需要获取到相机的Texture。在查阅了EasyAR的API文档后,我们知道了,官方为我们封装了方法,可以直接调用;
首先我们获取到场景中的“CameraDevice”,找到他的CameraImageRenderer组件,直接调用官方的方法;
CameraImageRenderer cameraRenderer = GameObject.Find("AR Session (EasyAR)/Camera Device").GetComponent();
cameraRenderer.RequestTargetTexture(targetTextureEventHandler);
使用这个方法要注意,在用完后一定要调用释放资源的方法;
//释放资源!!! cameraRenderer.DropTargetTexture(targetTextureEventHandler);
因为二维码扫描的是Texture2D所以我们在获取了相机的Texture之后,需要对Texture进行处理,需要将Texture转换为Texture2D;这里可以使用RenderTexture作为媒介来进行转换;具体代码请看示例代码;
在获取二维码信息是,因为需要读取的是Color32的信息,所以,还需要对Texture进行处理;
因为,EasyAR的组件对需要显示的模型是自动控制的,而在这里,我们希望,在没有扫描出二维码信息的时候不显示,并且能够根据不同的二维码显示不同的信息;
所以,我们需要关闭EasyAR的Target的自动显示功能;
GetComponent示例代码().ActiveControl = TargetController.ActiveControlStrategy.None;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using easyar;
using ZXing;
using UnityEngine.UI;
using System;
//读取摄像头图像
//扫描二维码
//如果和预设信息一致就显示模型
public class ScanQRCode : MonoBehaviour
{
public Text isScanBool;
public Text scanMessage;
public GameObject cube;
public GameObject spare;
public GameObject trucker;
///
/// 扫描时间间隔
///
float interval = 0.5f;
///
/// 32位颜色信息
///
Color32[] data;
///
/// 用来存储相机贴图信息
///
Texture camTexture;
///
/// 识别结果
///
Result result;
///
/// 二维码识别
///
BarcodeReader barcodeReader;//库文件对象 二维码信息保存的地方
///
/// 是否显示模型
///
public bool isShow ;
private Action targetTextureEventHandler;
///
/// 是否开始扫描
///
private bool isScan = false;
private void Awake()
{
targetTextureEventHandler = (camera, texture) =>
{
if (texture)
{
//获取相机纹理贴图
camTexture = texture;
}
};
}
private void Start()
{
isShow = false;
//ImageTrackerframeFilter m_imageTrackerframeFilter = trucker.GetComponent();
//因为我们要让GameObject在扫描识别到二维码之后显示对应的GameObject
//所以让显示GameObject不接受EasyAR的自动控制
GetComponent().ActiveControl = TargetController.ActiveControlStrategy.None;
}
private void FixedUpdate()
{
StartScan();
ScanInterval(3);
}
///
/// 扫描间隔
///
/// 间隔时间
void ScanInterval(float s_interval)
{
if (isScan)//开始扫描
{
interval += Time.deltaTime;
if (interval >= s_interval)
{
interval = 0;//重置计时器
Scan();//扫描
}
}
}
///
/// 开启扫描
///
void StartScan()
{
//如果扫描到了目标就开启扫描
if (GetComponent().IsTracked)
{
barcodeReader = new BarcodeReader();
//开始扫描
isScan = true;
isScanBool.text = "true";
}
else
{
isScan = false;
isScanBool.text = "false";
isShow = false;
spare.SetActive(false);
cube.SetActive(false);
}
}
///
/// 扫描二维码
///
void Scan()
{
scanMessage.text = "StartScan";
CameraImageRenderer cameraRenderer = GameObject.Find("AR Session (EasyAR)/Camera Device").GetComponent();
cameraRenderer.RequestTargetTexture(targetTextureEventHandler);
scanMessage.text = "GetCamera";
//转换成TEXTURE2D并获取color32数据信息
data = TextureToTexture2D(camTexture).GetPixels32();
//获取二维码信息
result = barcodeReader.Decode(data, camTexture.width, camTexture.height);
scanMessage.text = "ScanQRCode";
if (result != null)
{
isScan = false;
isScanBool.text = "false";
isShow = true;
scanMessage.text = result.Text;
if (result.Text == "cube0" || result.Text == "Cube0")
{
cube.SetActive(true);
}
if (result.Text == "spare0" || result.Text == "Spare0")
{
spare.SetActive(true);
}
//释放资源!!!
cameraRenderer.DropTargetTexture(targetTextureEventHandler);
}
else
{
isShow = false;
spare.SetActive(false);
cube.SetActive(false);
}
}
///
/// 转换成2D纹理
///
/// 需要转换的纹理
///
private Texture2D TextureToTexture2D(Texture texture)
{
Texture2D texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false);
RenderTexture currentRT = RenderTexture.active;
RenderTexture renderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 32);
Graphics.Blit(texture, renderTexture);
RenderTexture.active = renderTexture;
texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
texture2D.Apply();
RenderTexture.active = currentRT;
RenderTexture.ReleaseTemporary(renderTexture);
return texture2D;
}
}
将脚本挂载在Image Target下就可以了,并将对应的参数设置好;
将ImageTarget下的Cube和Sphere隐藏掉
直接打包成APK,在手机上进行运行测试;
测试效果 参考文章(31条消息) Unity技术分享之Unity中Texture和Texture2D格式互相转换_月儿圆-CSDN博客_unity的texture2dhttps://blog.csdn.net/s15100007883/article/details/80411638?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164188209416780255241008%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164188209416780255241008&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-80411638.first_rank_v2_pc_rank_v29&utm_term=unity+texture%E8%BD%ACtexture2d&spm=1018.2226.3001.4187



