Animator 的制作:
导入模型动画和特效资源包(连接我会放在文章的最后面),新建文件夹Animator(制作模型动画)和Prafbs(存放使用的模型).
在Animator文件夹新建一个Animator组件,并双击打开动画制作管理界面
然后新建一个空的模型状态(想做几个过渡就新建几个),然后再给这几个模型状态进行连接,连接过后如果想要循环播放,只要把最后一个模型状态动画和第一个模型状态动画连接在一就可以了,具体操作:
最终的动画效果图:并且最后的最后不要忘记给最初的模型添加好我们已经制作好了的动画——AnimatorController(我是重新命名了的),拖拽过来就行了.
Vuforia的环境搭建
在这里我用的U3D版本号时2017.3.1f1,在安装的时候已经是勾选了U3D内嵌的Vuforia开发组件的(勾选了就会出现以下图片的界面,如果没有的话的你也可以在U3D官网下载Installer,安装的时候只需要勾选Vuforia就可以了,或者市区Vuforia的官网下载SDK For Unity3D.),然后去Vuforia官网建立一个数据库并且获取LiscensKey(这个密钥的获取方式,网上教材很多,这里就不进行赘述了,这个密钥是对后续工作做了准备的)。密钥准备好以后还要进行一些设置,不然扫描图片以后根本无法出现模型,效果也是没有的,第一把世界中心模式设置为扫描的第一张图片,第二个是设置加载数据库,并把属性改为激活。
接下来有了正式的环境以后,我们就去搭建图片识别(Imgae Target)的开发了:首先在Hierarchy面板新建一个ARcamera和Image,给Image Target选择你之前在Vuforia建立好的数据库,并且选择Target Name。接着就时输入密钥了(进行初始化)。密钥的输入有两种方式:第一种(鼠标点击ARCamera,再点击Open Vuforia configuration);第二种(直接在搜索框里面搜索:Open Vuforia configuration,搜索到以后双击打开就可以看到密钥的输入界面了)(我只列出了第一种方式的图片)
Image Target中的DTEH C Sharp 脚本的分析
这个脚本我们打开后其实是利用了模型当中的Render组件控制,当摄像机识别到图片目标以后,我们就打开这个Render(被设置为True),当摄像机没有识别到图片目标以后,我们就关闭这个Render(被设置为False)。而我们必须要实现这个动画效果(即只要扫描到了图片,就展示模型,并且播放模型动画),这是就要对起代码进行改进,达到Animator与ImageTargetController加载在一起(下面的代码是针对DTEH对于实现追踪成功后生成模型与动画),并且修改好以后,拖拽Prefab(AIXI)过来。除此之外还要把Image的子物体模型AIXI的勾勾去掉(因为我们已经在脚本中实现了找到识别图生成模型的功能),不然就会出现Clone并没有销毁(Clone函数中的名称必须和Hierarchy中的创建的名称一样,其他随便)
public GameObject AIXIPrefab;
protected virtual void OnTrackingFound()
{
//找到了需要识别的物体
//找到以后生成AIXI
GameObject AIXI=GameObject.Instantiate(AIXIPrefab);
//把AIXI的位置放在识别图的位置
AIXI.transform.position = this.transform.position;
//把AIXI的主体设置Target的主体
AIXI.transform.parent = this.transform;
}
protected virtual void OnTrackingLost()
{
//丢失了需要识别的物体,只需要进行摧毁即可
Destroy(GameObject.Find("AIXI(Clone)"));
}
我们可以进行测试上面代码的编辑结果,找到生成Clone,丢失销毁克隆体。
public GameObject AIXIPrefab;
public GameObject HeianPrefab;
public GameObject TonadoPrefab;
protected virtual void OnTrackingFound()
{
//找到了需要识别的物体
//找到以后生成AIXI
GameObject ax=GameObject.Instantiate(AIXIPrefab);
//把AIXI的位置放在识别图的位置
ax.transform.position = this.transform.position;
//把AIXI的主体设置Target的主体
ax.transform.parent = this.transform;
//找到以后生成特效1,后面个参数分别是与识别位置一致,特效进行旋转
GameObject ef1=GameObject.Instantiate(HeianPrefab,transform.position,Quaternion.identity);
ef1.transform.parent = this.transform;
//特效生成10s后销毁
Destroy(ef1,10.0f);
//找到以后生成特效2,后面个参数分别是与识别位置一致,特效进行旋转
GameObject ef2=GameObject.Instantiate(TonadoPrefab,transform.position,Quaternion.identity);
ef2.transform.parent = this.transform;
Destroy(ef2,10.0f);
}
protected virtual void OnTrackingLost()
{
//丢失了需要识别的物体,只需要进行摧毁即可
Destroy(GameObject.Find("AIXI(Clone)"));
//丢失以后销毁特效
Destroy(GameObject.Find("Heian(Clone)"));
Destroy(GameObject.Find("Tonado(Clone)"));
}
//这个是我们需要在之前的基础上更改的DTEH代码部分
protected virtual void OnTrackingFound()
{
//找到了需要识别的物体
//找到以后生成AIXI,并且把模型位置向下移动
GameObject ax=GameObject.Instantiate(AIXIPrefab,transform.position-new Vector3(0,1.6f,0),transform.rotation);
//把AIXI的主体设置Target的主体
ax.transform.parent = this.transform;
//找到以后生成特效1,后面个参数分别是与识别位置一致,特效进行旋转
GameObject ef1=GameObject.Instantiate(HeianPrefab,transform.position,Quaternion.identity);
ef1.transform.parent = this.transform;
//特效生成10s后销毁
Destroy(ef1,6.0f);
//找到以后生成特效2,后面个参数分别是与识别位置一致,特效进行旋转
GameObject ef2=GameObject.Instantiate(TonadoPrefab,transform.position,Quaternion.identity);
ef2.transform.parent = this.transform;
Destroy(ef2,6.0f);
}
下面这个代码这个是新建的人物上升代码,挂载在AIXI上面,挂载好以后别忘记了Apply
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShangSheng : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//如果模型上升的位置完全在识别图上面时
if (transform.localPosition.y > 0) {
return;
}
//实现模型从识别图以下位置到以上位置的缓慢上升
transform.Translate (new Vector3 (0, 0.5f, 0) * Time.deltaTime);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScreenShot : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void OnScreeenShotClick()
{
//定义截图的时间,并设置成XX-XX——XX的格式
System.DateTime now = System.DateTime.Now;
string times = now.ToString ();
times = times.Trim ();
times = times.Replace ("/", "-");
//定义的J截图的文件名称
string fileName = "ARScreenShot" + times + ".png";
//当运行在安卓手机的时候 我们把截图放置在手机在带的截图文件夹里面
if (Application.platform == RuntimePlatform.Android) {
//采用Texture2D的格式
Texture2D texture = new Texture2D (Screen.width, Screen.height,TextureFormat.RGB24, false);
//截取全屏后读取贴图texture
texture.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0);
texture.Apply ();
//把截屏图片转换成二进制码储存在bytes中
byte[] bytes = texture.EncodeToPNG ();
//指定截图的路径
string destination = "/sdcard/DCIM/Screenshots";
string pathSave = destination + "/" + fileName;
}
}
}
在新建一个Button(UI里面的这些组件都必须放在一个画布上——Canvas),button的防止有一个小技巧那就是在Anchor界面上,先按住键盘上面的Alt键,在选择你的位置就可以了(左上就是TopLeft)
最后再把前面编辑好的ScreenShot脚本挂载在Canvas上面,再去Button界面上添加功能函数(添加的步骤如下图所示,把Canvas拖拽过来后,再去Function里面寻找ScreenShot脚本里面的OnScreenShotClick方法);
SIKI视频传送门( 里面有资源链接哟:课程资料【第一课的】)