模型OffTarget的原理:通过脚本实现图片识别之后,当识别图离开镜头的时候将模型固定在镜头前。
模型OffTarget的实现方法:第一步先搭建Vuforia的基础开发环境,具体流程可参照备注:https://www.cnblogs.com/mrmocha/p/9737448.html
1、在Hierrarchy视图空白处右键,创建一个空物体,命名为OffTargetPositionObject,拖到Camera物体下。
2、将要进行OffTarget的物体拖到OffTargetPositionObject下,并移动OffTargetPositionObject到ArCamera前,此时要保证OffTarget的物体在OffTargetPositonObject物体下的position为0。
3、在ImageTarget下面新建一个空物体,命名为Mgr,将要OffTarget的物体到Mgr下,保证Mgr和物体position为0。
4、此时,我们新建两个C#脚本,一个命名为OffTargetTrackableEventHandler,一个命名为OffTargetMgr。
6、打开ImageTarget上的DefaultTrackableEventHandler脚本,按Ctrl+A全选Ctrl+C复制,打开OffTargetTrackableEventHandler脚本,Ctrl+A全选,Ctrl+V粘贴,记住修改类名与脚本名保持一致,否则会报错。
7、打开OffTargetMgr脚本,键入以下代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OffTargetMgr : MonoBehaviour {
//要OffTarget的物体
public GameObject OffTargetObject;
//摄像机下的物体
public GameObject OffTargetPositionObject;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnEnable()
{
//在此脚本启用时,将OffTarget的父物体设定为挂载了这个脚本的物体,并且把本地位置和本地角度设置为0。
OffTargetObject.transform.parent = this.transform;
OffTargetObject.transform.localPosition = new Vector3(0, 0, 0);
OffTargetObject.transform.localEulerAngles = new Vector3(0, 0, 0);
}
void OnDisable()
{
//在此脚本关闭时,将OffTarget的父物体设定为摄像机下的空物体,并且把本地位置和本地角度设置0。
OffTargetObject.transform.parent = OffTargetPositionObject.transform;
OffTargetObject.transform.localPosition = new Vector3(0, 0, 0);
OffTargetObject.transform.localEulerAngles = new Vector3(0, 0, 0);
}
}
8、将OffTargetMgr挂载在ImageTarget下的Mgr上,并将要OffTarget的物体和OffTargetPositionObject物体拖入,并将OffTargetMgr脚本关闭勾选。
9、将ImageTarget物体上的DefaultTrackableEventHandler脚本Remove Component,将OffTargetTrackableEventHandler挂载在ImageTarget上。
10、在OffTargetTrackableEventHandler脚本中键入以下代码
/*==============================================================================
Copyright (c) 2010-2014 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
Confidential and Proprietary - Protected under copyright and other laws.
==============================================================================*/
using UnityEngine;
namespace Vuforia
{
/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class OffTargetTrackableEventHandler : MonoBehaviour,
ITrackableEventHandler
{
#region PRIVATE_MEMBER_VARIABLES
private TrackableBehaviour mTrackableBehaviour;
#endregion // PRIVATE_MEMBER_VARIABLES
#region UNTIY_MONOBEHAVIOUR_METHODS
void Start()
{
mTrackableBehaviour = GetComponent<TrackableBehaviour>();
if (mTrackableBehaviour)
{
mTrackableBehaviour.RegisterTrackableEventHandler(this);
}
}
#endregion // UNTIY_MONOBEHAVIOUR_METHODS
#region PUBLIC_METHODS
/// <summary>
/// Implementation of the ITrackableEventHandler function called when the
/// tracking state changes.
/// </summary>
public void OnTrackableStateChanged(
TrackableBehaviour.Status previousStatus,
TrackableBehaviour.Status newStatus)
{
if (newStatus == TrackableBehaviour.Status.DETECTED ||
newStatus == TrackableBehaviour.Status.TRACKED ||
newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
{
OnTrackingFound();
}
else
{
OnTrackingLost();
}
}
#endregion // PUBLIC_METHODS
#region PRIVATE_METHODS
private void OnTrackingFound()
{
//获取这个物体下的第一个子物体上的OffTargetMgr脚本,并且启用它。
this.transform.GetChild(0).GetComponent<OffTargetMgr>().enabled = true;
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
// Enable rendering:
foreach (Renderer component in rendererComponents)
{
component.enabled = true;
}
// Enable colliders:
foreach (Collider component in colliderComponents)
{
component.enabled = true;
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
}
private void OnTrackingLost()
{
//获取这个物体下的第一个子物体上的OffTargetMgr脚本,并且关闭它。
this.transform.GetChild(0).GetComponent<OffTargetMgr>().enabled = false;
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
// Disable rendering:
foreach (Renderer component in rendererComponents)
{
component.enabled = false;
}
// Disable colliders:
foreach (Collider component in colliderComponents)
{
component.enabled = false;
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
}
#endregion // PRIVATE_METHODS
}
}
11、保存并且运行,模型内容OffTarget完成。
视频OffTarget的原理:通过脚本实现图片识别之后,当识别图离开镜头的时候将视频自动全屏播放或在镜头前播放。
视频OffTarget的实现方法:搭建视频播放的环境,具体流程可参照备注:http://blog.youkuaiyun.com/wene_zheng/article/details/52223958
1~3步和上面的一样,都是在Camera下面创建一个空物体。
4、新建两个脚本,分别命名为VideoOffTargetMgr和VideoTrackableEventHandler。
5、复制TrackableEventHandler内容到VideoTrackableEventHandler脚本里,记得修改类名,然后将ImageTarget上的TrackableEventHandler去掉换成VideoTrackableEventHandler,VideoTrackableEventHandler脚本内容如下。
/*==============================================================================
* Copyright (c) 2012-2015 Qualcomm Connected Experiences, Inc. All Rights Reserved.
* ==============================================================================*/
using UnityEngine;
using Vuforia;
/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class VideoTrackableEventHandler : MonoBehaviour, ITrackableEventHandler
{
#region PRIVATE_MEMBERS
private TrackableBehaviour mTrackableBehaviour;
private bool mHasBeenFound = false;
private bool mLostTracking;
private float mSecondsSinceLost;
#endregion // PRIVATE_MEMBERS
#region MONOBEHAVIOUR_METHODS
void Start()
{
mTrackableBehaviour = GetComponent<TrackableBehaviour>();
if (mTrackableBehaviour)
{
mTrackableBehaviour.RegisterTrackableEventHandler(this);
}
OnTrackingLost();
}
void Update()
{
// Pause the video if tracking is lost for more than two seconds
if (mHasBeenFound && mLostTracking)
{
if (mSecondsSinceLost > 2.0f)
{
VideoPlaybackBehaviour video = GetComponentInChildren<VideoPlaybackBehaviour>();
if (video != null &&
video.CurrentState == VideoPlayerHelper.MediaState.PLAYING)
{
video.VideoPlayer.Pause();
}
mLostTracking = false;
}
mSecondsSinceLost += Time.deltaTime;
}
}
#endregion //MONOBEHAVIOUR_METHODS
#region PUBLIC_METHODS
/// <summary>
/// Implementation of the ITrackableEventHandler function called when the
/// tracking state changes.
/// </summary>
public void OnTrackableStateChanged(
TrackableBehaviour.Status previousStatus,
TrackableBehaviour.Status newStatus)
{
if (newStatus == TrackableBehaviour.Status.DETECTED ||
newStatus == TrackableBehaviour.Status.TRACKED ||
newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
{
OnTrackingFound();
}
else
{
OnTrackingLost();
}
}
#endregion //PUBLIC_METHODS
#region PRIVATE_METHODS
private void OnTrackingFound()
{
this.transform.GetChild(0).GetComponent<VideoOffTargetMgr>().enabled = true;
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>();
Collider[] colliderComponents = GetComponentsInChildren<Collider>();
// Enable rendering:
foreach (Renderer component in rendererComponents)
{
component.enabled = true;
}
// Enable colliders:
foreach (Collider component in colliderComponents)
{
component.enabled = true;
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
// Optionally play the video automatically when the target is found
VideoPlaybackBehaviour video = GetComponentInChildren<VideoPlaybackBehaviour>();
if (video != null && video.AutoPlay)
{
if (video.VideoPlayer.IsPlayableOnTexture())
{
VideoPlayerHelper.MediaState state = video.VideoPlayer.GetStatus();
if (state == VideoPlayerHelper.MediaState.PAUSED ||
state == VideoPlayerHelper.MediaState.READY ||
state == VideoPlayerHelper.MediaState.STOPPED)
{
// Pause other videos before playing this one
PauseOtherVideos(video);
// Play this video on texture where it left off
video.VideoPlayer.Play(false, video.VideoPlayer.GetCurrentPosition());
}
else if (state == VideoPlayerHelper.MediaState.REACHED_END)
{
// Pause other videos before playing this one
PauseOtherVideos(video);
// Play this video from the beginning
video.VideoPlayer.Play(false, 0);
}
}
}
mHasBeenFound = true;
mLostTracking = false;
}
private void OnTrackingLost()
{
this.transform.GetChild(0).GetComponent<VideoOffTargetMgr>().enabled = false;
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>();
Collider[] colliderComponents = GetComponentsInChildren<Collider>();
// Disable rendering:
foreach (Renderer component in rendererComponents)
{
component.enabled = false;
}
// Disable colliders:
foreach (Collider component in colliderComponents)
{
component.enabled = false;
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
mLostTracking = true;
mSecondsSinceLost = 0;
}
// Pause all videos except this one
private void PauseOtherVideos(VideoPlaybackBehaviour currentVideo)
{
VideoPlaybackBehaviour[] videos = (VideoPlaybackBehaviour[])
FindObjectsOfType(typeof(VideoPlaybackBehaviour));
foreach (VideoPlaybackBehaviour video in videos)
{
if (video != currentVideo)
{
if (video.CurrentState == VideoPlayerHelper.MediaState.PLAYING)
{
video.VideoPlayer.Pause();
}
}
}
}
#endregion //PRIVATE_METHODS
}
6、将VideoOffTarget脚本挂在ImageTarget物体下的Mgr上,VideoOffTarget脚本内容如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VideoOffTargetMgr : MonoBehaviour {
public GameObject VideoObject;
public GameObject OffTargetObject;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnEnable()
{
VideoObject.transform.parent = this.transform;
VideoObject.transform.position = new Vector3(0,0,0);
VideoObject.transform.eulerAngles = new Vector3(0, 0, 0);
}
void OnDisable()
{
VideoObject.transform.parent = OffTargetObject.transform;
VideoObject.transform.position = new Vector3(0, 0, 0);
VideoObject.transform.eulerAngles = new Vector3(0, 0, 0);
/*全屏播放方法如下
Handheld.PlayFullScreenMovie("VuforiaSizzleReel_1.mp4", Color.black, FullScreenMovieControlMode.CancelOnInput);
括号中第一个参数为视频路径,第二个为背景颜色,第三个为播放模式。*/
}
}
7、打包成安卓或者IOS包,在手机上运行,电脑上无法播放视频(使用Vuforia自带视频插件时)。