利用Vuforia开发一个AR卡牌对战(一):多图识别+EventHandler框架

来源:互联网 发布:three.js 案例 编辑:程序博客网 时间:2024/05/26 22:59

卡牌对战1:多图识别+EventHandler框架

这个系列主要讲解实现一个简易的AR卡牌对战的功能,这次首先实现多图识别和EventHandler的框架介绍。

首先我们来实现多图识别。

1.上传识别图并下载数据包,然后得到LicenseKey。这里用了两个识别图,一次打包两个识别图下载下来。

 

两个识别图分别是

2.Vuforia插件导入Unity,并将识别图数据包导入,拖入ARCamera和两个ImageTarget

 

3.设置ARCamera:输入LicenseKey,然后设置Max Simultaneous Tracked Images为最多识别的图片数目(这里设置为2),这是单图识别和多图识别的主要区别。

 

4.分别设置两个ImageTarget,同一个Database下两个不同图片

 

5.不要忘记设置他们的材质的TextureShape2DEditor-Vuforia-ImageTargetTextures下选择识别图材质然后设置。

6.测试效果,分别在两个识别图下放一个Cube和一个Sphere.

可以看到,在选择一个ImageTarget的时候两个ImageTarget的图片却变成相同的了,不过这并不影响我们的识别的功能。

 

7.运行测试,多图识别就基本好了。

 

 

二、Trackable Event Handler 框架的介绍:

一般我们做识别是不会在别人的源代码上直接修改的,所以这边我们复制他的DefaultTrackableEventHandler脚本代码,自己新建一个脚本

My_DefaultTrackableEventHandler2,然后复制他的代码到这个脚本上并修改类名为自己的脚本名字。下面是代码和注释,都是一些个人的理解。

using UnityEngine;namespace Vuforia{    /// <summary>    /// A custom handler that implements the ITrackableEventHandler interface.    /// </summary>    public class My_DefaultTrackableEventHandler2 : MonoBehaviour,                                                ITrackableEventHandler //实现ITrackableEventHandler接口,该接口函数是OnTrackableStateChanged    {        #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>        //该方法功能是监测摄像头的追踪状态,检测到识别图的时候执行OnTrackingFound();丢失的时候执行OnTrackingLost();        //在丢失的时候和追踪到的时候分别都执行一次,而不是在丢失的状态下一直执行,在找到的状态下一直执行。        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         //识别到的时候        //将所挂在这个脚本的ImageTarget下的所有子物体的Renderer和Collider打开(enabled)        private void OnTrackingFound()        {            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");        }         //识别丢失的时候        //将所挂在这个脚本的ImageTarget下的所有子物体的Renderer和Collider关闭(disabled)               private void OnTrackingLost()        {            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         //丢是识别图的时候,是不再渲染模型和不再计算碰撞了,而不是消除了物体(有需要的话也可以这么做来动态加载物体)    }}


由于我们做的是AR卡牌对战,所以下一节需要在OnTrackingFound和OnTrackingLost方法中做一些修改,来达到我们想要的目的。

三、准备工作和模型的导入。

我们要实现的基本功能:AR多卡识别;两张卡距离满足一定条件的时候触发对战事件,否则就待机;远程人物攻击时炮弹能追踪目标;卡片距离到一定距离的时候人物开始向对方移动,然后到了攻击范围就开始攻击;双方有各自的血条。

人物模型和动画的导入:我这边随意的准备了人物模型,这边修改动画和触发条件,动画分别为IdleRunAttackTauntDeadDie 5个动画(RunIdle需要循环播放),这些转换条件

 

只有最下面的是Trigger,其他都是Bool类型,将AnyStateDie的触发条件,IdleRunRunAttack触发条件中的HasExitTime去掉

 

分别设置转换条件,设置完成后任务动画基本就OK了,接下来在制作一个血条,一个白色的长方形图片就可以了,这里命名为Blood,然后设置为Sprite

将人物模型拖到识别图下,并给模型添加刚体和碰撞,不需要重力和其他受力旋转啥的,所以都去掉。

 

给给近战角色的武器上添加一个碰撞器,勾选Trigger

 

给远程人物新建一个球来当他的子弹,球上也要挂碰撞(Trigger)。

 

 

最后再把血条加上去:在模型的下面分别添加Cavans,换成世界坐标,然后添加Image,将Blood.jpg赋值上去,调整大小和颜色到下图所示:

 

 

到这我们的基本的准备工作就OK了,有什么不合理的地方或者缺什么,下一次边做边修改。

本文内容部分参考自Think加速想象力出版的《ARVR开发实战》教程,更多学习资料也请关注www.arvrthink.com

 

阅读全文
2 0
原创粉丝点击