美文网首页AR/VR/MRAR
AR开发实战Vuforia项目之AR寻宝(实现与服务器对接功能)

AR开发实战Vuforia项目之AR寻宝(实现与服务器对接功能)

作者: TonyWan_AR | 来源:发表于2018-04-26 14:40 被阅读945次

    一、框架视图

    二、关键代码

    CameraMode

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Vuforia;
    
    
    public class CameraMode : MonoBehaviour
    {
    
        /// <summary>
        /// 高通摄像头对焦功能
        /// </summary>
        void Start()
        {
            VuforiaARController.Instance.RegisterVuforiaStartedCallback(OnVuforiaStarted);
            VuforiaARController.Instance.RegisterOnPauseCallback(OnPaused);
        }
    
        void Update()
        {
    
        }
        private void OnVuforiaStarted()
        {
            CameraDevice.Instance.SetFocusMode(
            CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
        }
    
        private void OnPaused(bool paused)
        {
            if (!paused)
            { // resume
                CameraDevice.Instance.SetFocusMode(
                CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
            }
        }
       
    }
    
    
    

    CoinMannge

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;
    using System;
    using DG.Tweening;
    
    
    
    public class CoinMannger : MonoBehaviour
    {
        public GameObject[] AllGoes; //储存所有目标图片 30张
        public Camera mCamera; //渲染Ar相机为实现相机跟随物体的引用
        public GameObject coinPrefabs;//5G币的预制体
        public GameObject[] goldCoins; //储存生成的5G币
        public GameObject redPack;   //红包动画
        private  Vector3 worldPos; //世界坐标
        public GameObject PromptTxt; //提示语储存游戏对象
        private int number=0; //初始值硬币数为零
        public  Text ScroreTxt; //获得金币的总数文本
        public GameObject ScanFrame; //扫描框
        private   AudioSource mAudioSource; //声音文件的引用
        public AudioClip bgClip; //背景音乐
        public AudioClip hahaClip;//哈哈提示声
        public AudioClip noCoinClip; //没有金币的提示声
        public AudioClip foundAllClip; //找到所有金币
        public  bool isPlayFoundAll; //是否找到所有金币或者已经满5次的标志位
        public bool notFoud; //没有金币或者已经扫描过的金币
        private string regInfo; //提示语信息
        private string mToken; //Token码的引用
        private bool isTokenUseless = true; //Token是否失效
        private string scanImgId; //扫描图片的ID号
        public Text RCountTxt; //弹框红包显示本次获得多少个金币
        public GameObject Img_Bounced; //弹框红包
        public bool isClickPack=true; //是否点击红包的标志位 默认为true
    
        //接口说明:返回用户扫红包的总次数,5g币数,扫过的红包图片id
        //测试请求地址:http://www.top/app/arRedPacket/listRed?token=xxx
        //正式请求地址:http://www.vip/app/arRedPacket/listRed?token=xxx
    
        private string getListRedUrl = @"http://www.top/app/ar/arRedPacket/listRed?token={0}"; //红包信息
                                                                                                          //private string getListRedUrl = @"http://www.vip/app/ar/arRedPacket/listRed?token={0}"; //红包信息
    
    
    
        // 接口说明:返回图片次数
        // 测试请求地址:http://www.top/app/arRedPacket/imgCount?imgId=xx&token=xxx
        //正式请求地址:http://www.vip/app/arRedPacket/imgCount?imgId=x&token=xxx
    
        private string getScanRedUrl = @"http://www.top/app/arRedPacket/imgCount?imgId={0}&token={1}"; //接收红包信息
                                                                                                                     //private string getScanRedUrl = @"http://www.vip/app/ar/arRedPacket/imgCount?imgId={0}&token={1}"; //接收红包信息
    
    
        //接口说明:扫描图片
        //测试请求地址:http://www.top/app/arRedPacket/scanningRed?imgId=xx&gbNumber=xx&token=xx
        //正式请求地址:http://www.vip/app/arRedPacket/scanningRed?imgId=xx&gbNumber=xx&token=xx
    
        private string sendScanRedUrl = @"http://www.top/app/arRedPacket/scanningRed?imgId={0}&gbNumber={1}&token={2}"; //发送红包信息
       // private string sendScanRedUrl = @"http://www.vip/app/arRedPacket/scanningRed?imgId={0}&gbNumber={1}&token={2}"; //发送红包信息
    
        void Start()
        {
            //声效的引用
            mAudioSource = gameObject.GetComponent<AudioSource>();
            mAudioSource.clip = bgClip; //背景声
            mAudioSource.volume = 1f;
            mAudioSource.pitch = 1f;
            mAudioSource.loop = true;
            mAudioSource.Play(); //播放背景声
            mToken = PlayerPrefs.GetString("mToken"); //获取Token码
            GetRedStatus_OnGetRedPackStatus(mToken); //获取用户扫描图片(红包)信息接口
            //Debug.Log(PlayerPrefs.GetString("mToken"));
            worldPos = new Vector3(0, 0, 0); //世界坐标
        }
    
    
        void Update()
        {
            if (ScanFrame.activeSelf)
            {
                ScanFrame.transform.Rotate(new Vector3(0, 0, -1)); //扫描框旋转
            }
           
        }
    
        /// <summary>
        ///找到目标 发现目标
        /// </summary>
        /// <param name="imgId">图片ID号</param>
        public void FoundTarget(string imgId)
        {
            StopAllCoroutines(); //避免出现bug,在此满足发现条件时取消所有协程
            ScanFrame.SetActive(false); //隐藏扫描框
            scanImgId = imgId;//图片ID号
            GetRedStatus_OnScanForwardRedPackStatus(scanImgId, mToken);//调用获取用户红包信息的接口(扫描前)动画弹出来前的判断接口
    
        }
    
    
    
        
        /// <summary>
        /// 实例化金币的过程
        /// </summary>
        public void InitCoin() {
    
            goldCoins = new GameObject[UnityEngine.Random.Range(1, 5)]; //随机1-5个金币的长度
            RCountTxt.text = goldCoins.Length+"个"; //弹框红包的文本显示
            number+= goldCoins.Length; //总数累加
            for (int i = 0; i < goldCoins.Length; i++) //实例化金币 5秒后销毁
            {
                goldCoins[i] = GameObject.Instantiate(coinPrefabs, worldPos, Quaternion.identity);  
                Destroy(goldCoins[i], 5f); 
            }
            //相机跟随金币 控制物体在相机框内掉落
            mCamera.transform.position = new Vector3(goldCoins[goldCoins.Length-1].transform.position.x, goldCoins[goldCoins.Length - 1].transform.position.y + 10, goldCoins[goldCoins.Length - 1].transform.position.z + 10);
            mCamera.transform.LookAt(goldCoins[goldCoins.Length - 1].transform); //相机朝向最后一个金币位置
            //PlayerPrefs.SetInt("Score", number); //设置储存金币总数
            StartCoroutine("RedTxtDelayShow"); //显示弹框红包的过程
        
        }
    
    
        /// <summary>
        /// 弹框红包的协程 
        /// </summary>
        /// <returns></returns>
        IEnumerator RedTxtDelayShow()
        {
            yield return new WaitForSeconds(2f); //等待金币掉落2秒后显示红包 
            GetRedStatus_OnScanFinishRedPackStatus(scanImgId, goldCoins.Length, mToken); //获取金币后把图片ID号 金币数量 Token调用接口传回去
            Img_Bounced.SetActive(true); //显示弹框红包
            Img_Bounced.transform.localScale = new Vector3(0,0,0); //设置初始化尺寸
            Img_Bounced.transform.DOScale(new Vector3(1, 1, 1), 0.5f); //dotween动画过程
            ScroreTxt.text = "恭喜您已获得" + number + "个5G币!"; //底部显示金币总数量
    
           
        }
    
    
        /// <summary>
        /// 没有找到目标 没有金币 或已扫描过的方法
        /// </summary>
        public void NotFoundTarget()
        {
    
            if (notFoud==false)
            {
                if (isPlayFoundAll) //已找到5次目标
                {
                    mAudioSource.clip = foundAllClip; //声效赋值全部找到金币
                    PromptTxt.transform.GetComponent<Text>().text = "恭喜您已经抢到所有红包!";
                }
                else
                {
                    mAudioSource.clip = noCoinClip; //没有金币的声效
                    PromptTxt.transform.GetComponent<Text>().text = "这里已经没有5G币了···";
                }
                mAudioSource.volume = 1f;
                mAudioSource.pitch = 1f;
                mAudioSource.loop = false;
                mAudioSource.Play();//播放声效
                StartCoroutine(DelayHidden()); //开启延迟文字消失的过程 渐变
            }
           
    
        }
    
    
        /// <summary>
        /// 逐渐消失的过程
        /// </summary>
        /// <returns></returns>
        IEnumerator DelayHidden()
        {     
            PromptTxt.SetActive(true); //提示语显示
            yield return new WaitForSeconds(3.5f);
            mAudioSource.clip = bgClip; 
            mAudioSource.volume = 1f;
            mAudioSource.pitch = 1f;
            mAudioSource.loop = true;
            mAudioSource.Play();
            Component[] comps = PromptTxt.GetComponentsInChildren<Component>();
            foreach (Component c in comps)
            {
                if (c is Graphic)
                {
                    (c as Graphic).CrossFadeAlpha(0, 2, true);
                }
            }
            yield return new WaitForSeconds(1.5f);
            PromptTxt.SetActive(false); //提示语消失
            if (isTokenUseless==false)
            {
                //如果别的手机登录跳转到登录界面
                SceneManager.LoadScene("Login");
            }
        }
    
        /// <summary>
        /// 返回按钮
        /// </summary>
        public void ReturnBtn() {
            SceneManager.LoadScene("Login");
        }
    
        /// <summary>
        /// 退出按钮
        /// </summary>
        public void ExitBtn() {
    
            Application.Quit();
        }
    
        /// <summary>
        /// 点击 开 按钮 隐藏动画 实例化金币
        /// </summary>
        public void HideRedPack() {
    
            redPack.SetActive(false);
            InitCoin();
    
        }
    
        /// <summary>
        /// 登录成功后获取相关红包的信息 扫描,扫描次数 扫描过的图片id号 扫描过的金币数
        /// </summary>
        /// <param name="token">传回Token码</param>
        public void GetRedStatus_OnGetRedPackStatus(string token)
        {
    
            string url = string.Format(getListRedUrl, token);
            StartCoroutine(GetFromUrl_RedPack(url,
                (v) =>
                {
                    regInfo = v.code + v.imgIdTags + v.message+v.gbNumber+v.scanCount;
                    if (v.code== "1")  //获取状态码之后进行判断
                    {
                        number = v.gbNumber;
                        ScroreTxt.text = "您已获得" + number + "个5G币!";
                        if (v.scanCount==0) //5次扫描
                        {
                            PromptTxt.transform.GetComponent<Text>().text = "恭喜你,你有5次寻宝机会哦·";
                        }
                        else if (v.scanCount != 5) //剩下的次数
                        {
                            PromptTxt.transform.GetComponent<Text>().text = "来,来,来,你还有"+(5-v.scanCount)+"次寻宝机会哦·";
                        }
                        else //全部扫过
                        {
                            PromptTxt.transform.GetComponent<Text>().text = "恭喜您已经抢到所有红包!";
                            HideAllGameObject();
                            redPack.SetActive(false);
                            isPlayFoundAll = true; 
    
                        }
                        StartCoroutine(DelayHidden());  
                    }
                    else
                    {
                        PromptTxt.transform.GetComponent<Text>().text = "服务器内部错误,稍后再试";
                        StartCoroutine(DelayHidden());
                    }
    
                }
                ));
    
        }
    
        /// <summary>
        /// d登录成功后开启的网络协程
        /// </summary>
        /// <param name="url">接口</param>
        /// <param name="callback">回调</param>
        /// <returns></returns>
        IEnumerator GetFromUrl_RedPack(string url, Action<JsonRedList> callback)
        {
            WWW www = new WWW(url);
            yield return www;
            if (www.isDone && string.IsNullOrEmpty(www.error))
            {
                if (null != callback)
                {
                    string jsonStr = www.text.Trim();
                    JsonRedList jd = JsonUtility.FromJson<JsonRedList>(jsonStr);
                    callback.Invoke(jd);
                }
    
    
            }
            else
            {
                Debug.Log("网络错误" + www.error);
                PromptTxt.transform.GetComponent<Text>().text = "网络错误,请重新登录";
                DelayHidden();
            }
    
    
        }
    
        /// <summary>
        /// 扫描前的判断
        /// </summary>
        /// <param name="imgId">图片ID号</param>
        /// <param name="token">Token码</param>
        public void GetRedStatus_OnScanForwardRedPackStatus(string imgId, string token)
        {
    
            string url = string.Format(getScanRedUrl, imgId,token);
            StartCoroutine(GetFromUrl_ScanForwardRedPack(url,
                (v) =>
                {
                    regInfo =v.code +v.imgId +v.scanCount+ v.message;
                    if (v.code == "1") //成功返回信息
                    {
                        if (v.scanCount < 5) //少于5次播放音效 播放红包动画
                        {
                            mAudioSource.clip = hahaClip; 
                            mAudioSource.volume = 1f;
                            mAudioSource.pitch = 1f;
                            mAudioSource.loop = false;
                            mAudioSource.Play();
                            PromptTxt.transform.GetComponent<Text>().text = "哈哈,这都被你找到了···";
                            StartCoroutine(DelayHidden()); //文字逐渐消失过程
                            redPack.SetActive(true); //h红包动画
                        }
                        else //超过5次的就播放没有找到目标的方法
                        {                   
                            NotFoundTarget();
                            ScanFrame.SetActive(true); //扫描框显示
                        }
    
                    }
                    else if (v.code == "10") //表示已经抢过了此id图片红包
                    {
                        mAudioSource.clip = noCoinClip;  //没有红包的声效
                        NotFoundTarget(); 
                    }
                    else if (v.code == "88") //表示已经抢完所有红包 只是发现目标而已
                    {
                        mAudioSource.clip = foundAllClip; //所有红包声效
                        isPlayFoundAll = true;//所有红包的标志位
                        HideAllGameObject();//隐藏所有目标体
                        redPack.SetActive(false); //红包动画关闭
                        NotFoundTarget(); //没有发现目标的方法
                        PromptTxt.transform.GetComponent<Text>().text = "恭喜您已经抢到所有红包了!";
                        StartCoroutine(DelayHidden()); //文字逐渐消失的过程
                        ScanFrame.SetActive(true); //显示扫描框
                    }
                    else
                    {
                        PromptTxt.transform.GetComponent<Text>().text = "网络错误,请重新登录";
                        DelayHidden();
                    }
    
                }
                ));
    
        }
    
        /// <summary>
        /// 返回图片 被扫过的次数返回值
        /// </summary>
        /// <param name="url"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
    
        IEnumerator GetFromUrl_ScanForwardRedPack(string url, Action<JsonImgCount> callback)
        {
            WWW www = new WWW(url);
            yield return www;
            if (www.isDone && string.IsNullOrEmpty(www.error))
            {
                if (null != callback)
                {
                    string jsonStr = www.text.Trim();
                    JsonImgCount jd = JsonUtility.FromJson<JsonImgCount>(jsonStr);
                    callback.Invoke(jd);
                }
    
    
            }
            else
            {
                Debug.Log("网络错误" + www.error);
                PromptTxt.transform.GetComponent<Text>().text = "网络错误,请重新登录";
                DelayHidden();
            }
        }
    
    
    
    
      /// <summary>
      /// 扫描完成 金币生成完毕之后 把被扫描图片的id号 金币数 Token传回服务器
      /// </summary>
      /// <param name="imgId"></param>
      /// <param name="gbNumber"></param>
      /// <param name="token"></param>
        public void GetRedStatus_OnScanFinishRedPackStatus(string imgId,int gbNumber, string token)
        {
    
            string url = string.Format(sendScanRedUrl, imgId, gbNumber, token);
            StartCoroutine(GetFromUrl_ScanFinishRedPack(url,
                (v) =>
                {
                    regInfo =  v.code  + v.message ;
                    switch (v.code)
                    {
                        case "1":
                            //number
                            break;
                        case "422":
                            PromptTxt.transform.GetComponent<Text>().text = "你手机在别处登录···";        //Token失效           
                            isTokenUseless = false; //开启标志位
                            StartCoroutine(DelayHidden());  
                            break;
                        case "0":
                            Debug.Log("图片参数id不能为空");
                            break;
                        case "2":
                            Debug.Log("用户token不能为空!");
                            break;
                        case "10":
                            Debug.Log("您已经抢到红包,您还可以寻找另外的红包点!");
                            break;
                        case "88": //抢完所有红包
                            if (notFoud==false)
                            {
                                HideAllGameObject();
                                PromptTxt.transform.GetComponent<Text>().text = "恭喜您已经抢到所有红包了!";
                                isPlayFoundAll = true;
                                NotFoundTarget();
                            }
                            break;
                        case "500":
                            Debug.Log("服务器内部错误!");
                            break;
                        default:
                            PromptTxt.transform.GetComponent<Text>().text = "服务器内部错误,稍后再试";
                            StartCoroutine(DelayHidden());
                            break;
                    }      
    
                }
                ));
    
        }
    
        /// <summary>
        /// 扫描完成 把数据传回去开启网络协程
        /// </summary>
        /// <param name="url"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        IEnumerator GetFromUrl_ScanFinishRedPack(string url, Action<JsonSend> callback)
        {
            WWW www = new WWW(url);
            yield return www;
            if (www.isDone && string.IsNullOrEmpty(www.error))
            {
                if (null != callback)
                {
                    string jsonStr = www.text.Trim();
                    JsonSend jd = JsonUtility.FromJson<JsonSend>(jsonStr);
                    callback.Invoke(jd);
                }
    
    
            }
            else
            {
                Debug.Log("网络错误" + www.error);
                PromptTxt.transform.GetComponent<Text>().text = "网络错误,请重新登录";
                DelayHidden();
            }
        }
    
        /// <summary>
        /// 隐藏所有目标物体
        /// </summary>
        public void HideAllGameObject() {
    
            for (int i = 0; i < AllGoes.Length; i++)
            {
                AllGoes[i].SetActive(false);
            }
        }
    
    
    
        /// <summary>
        /// 世界坐标转换成屏幕坐标
        /// </summary>
        /// <param name="canvas"></param>
        /// <param name="worldGo"></param>
        /// <returns></returns>
        //public static Vector3 WorldToUIPoint(Canvas canvas, Transform worldGo)
        //{
        //    Vector3 v_v3 = Camera.main.WorldToScreenPoint(worldGo.position);
        //    Vector3 v_ui = canvas.worldCamera.ScreenToWorldPoint(v_v3);
        //    Vector3 v_new = new Vector3(v_ui.x, v_ui.y, canvas.GetComponent<RectTransform>().anchoredPosition3D.z);
         //  return v_new;
        //}
    
        public static Vector3 WorldToUI(Camera camera, Vector3 pos)
        {
            CanvasScaler scaler = GameObject.Find("Canvas").GetComponent<CanvasScaler>();
    
            float resolutionX = scaler.referenceResolution.x;
            float resolutionY = scaler.referenceResolution.y;
    
            Vector3 viewportPos = camera.WorldToViewportPoint(pos);
    
            Vector3 uiPos = new Vector3(viewportPos.x * resolutionX - resolutionX * 0.5f,
                viewportPos.y * resolutionY - resolutionY * 0.5f, 0);
    
            return uiPos;
        }
    
        /// <summary>
        /// Dotween开启 隐藏红包功能
        /// </summary>
        public void HideRedScoreBtn() {
    
           // StopCoroutine("RedTxtDelayHidden");
            StartCoroutine("DelaySetActive");
            //点击红包收缩 之后实例化金币紧张再设置为标志位true
            isClickPack = true;
        }
    
        /// <summary>
        /// 把红包金币数延迟隐藏
        /// </summary>
        /// <returns></returns>
        IEnumerator DelaySetActive()
        {
    
            Img_Bounced.transform.DOScale(new Vector3(0, 0, 0), 0.4f);//设置尺寸
            yield return new WaitForSeconds(1f);//延迟一秒之后
            Img_Bounced.SetActive(false); //获得金币数红包隐藏
            ScanFrame.SetActive(true); //扫描框显示
           //yield return new WaitForSeconds(1f);//延迟一秒之后
           //StopAllCoroutines(); //避免出现bug,在此满足发现条件时取消所有协程
        }
    
    }
    
    

    CoinTrackableEventHandler

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    //using UnityEngine.UI;
    
    
    namespace Vuforia
    {
        /// <summary>
        /// A custom handler that implements the ITrackableEventHandler interface.
        /// </summary>
        public class CoinTrackableEventHandler : MonoBehaviour,
                                                    ITrackableEventHandler
        {
            #region PRIVATE_MEMBER_VARIABLES
    
            private TrackableBehaviour mTrackableBehaviour;  //定义跟踪变量
            private List<GameObject> listGoes = new List<GameObject>(); //储存所有游戏物体
            #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();
                   if (gameObject.activeSelf == true && GameObject.Find("GoManager").transform.GetComponent<CoinMannger>().isClickPack == true) //如果当前扫描到的游戏物体是活跃的前提下才执行
                        //if (gameObject.activeSelf == true) //如果当前扫描到的游戏物体是活跃的前提下才执行
                        {
                        OnTrackingFound();
                        //找到对应物体下挂到脚本的发现目标的方法 传图片的ID号
                        GameObject.Find("GoManager").transform.GetComponent<CoinMannger>().FoundTarget(gameObject.transform.tag);
                        Debug.Log(gameObject.transform.tag);
                        gameObject.SetActive(false); //执行方法之后把自己物体隐藏掉
                                                     //设置点击红包标志位为不可执行
                        GameObject.Find("GoManager").transform.GetComponent<CoinMannger>().isClickPack = false;
                    }
                    else 
                    //if (gameObject.activeSelf == false )
                     //如果不是活跃的话
                    {
                        //判断红包是不是 隐藏状态 不播放
                        if (GameObject.Find("GoManager").transform.GetComponent<CoinMannger>().redPack.activeSelf == false&& GameObject.Find("GoManager").transform.GetComponent<CoinMannger>().Img_Bounced.activeSelf==false)
                        {
                            //执行没有发现目标的方法
                            GameObject.Find("GoManager").transform.GetComponent<CoinMannger>().NotFoundTarget();
                        }
    
                    }
                }
                else
                {
                    OnTrackingLost();
                    listGoes.Clear(); //清空游戏物体
                    StopAllCoroutines(); //停止所有的协程
                }
            }
    
            #endregion // PUBLIC_METHODS
    
    
    
            #region PRIVATE_METHODS
    
    
            private void OnTrackingFound()
            {
                if (gameObject.activeSelf == 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()
            {
                if (gameObject.activeSelf == true) //加个判断 物体是激活状态
                {
    
                    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
    
        }
    }
    
    

    JsonParsing

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /// <summary>
    /// 登录
    /// </summary>
    public class JsonLogin
    {
    
        public string code;
        public string token;
        public string message;
    }
    /// <summary>
    /// 获取图片被扫描的次数
    /// </summary>
    public class JsonImgCount
    {
    
        public string code;
        public int scanCount;
        public string imgId;
        public string message;
    }
    /// <summary>
    /// 个人用户获取红包相关信息
    /// </summary>
    public class JsonRedList
    {
    
        public string code;
        public string imgIdTags;
        public string message;
        public int gbNumber;
        public int scanCount;
    
    }
    
    /// <summary>
    /// 把扫描过执行生成金币后的相关信息传回后台
    /// </summary>
    public class JsonSend
    {
    
        public string code;
        public string message;
    }
    

    LoginCtrl

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;
    using System;
    using System.Text.RegularExpressions;//正则表达式
    
    public class LoginCtrl : MonoBehaviour {
    
        public InputField InputFieldMobile; //获取手机输入框内容
        public InputField InputFieldVerificationCode; //获取手机验证码输入框内容
        public Button Btn_Login; //登录按钮
        public string tokenCode; //token码
        public GameObject RegProImg; //提示信息游戏对象
        public string StatusNumber; //状态码
        private string promptTxt; //方便设施提示语
        private bool isTiming = false; //计时是否开始
        private int NowSecond; // 设置时间为60秒
        private int i = 0; //帧数开始渐变
        public Button Btn_Reset;    //重置 重新发送验证码
        private string regInfo; //Json解析出来状态信息
        //  1.检查手机是否注册并发送验证码
        //接口说明:检查手机是否有效,如果手机有效就发送验证码
        //测试请求地址:http://www.top/app/sendVerifiCode?mobile=13534226999
        //正式请求地址:http://www.vip/app/sendVerifiCode?mobile=13534226999
    
        private string sendVerifiCodeUrl = @"http://www.top/app/sendVerifiCode?mobile={0}";
        //private string sendVerifiCodeUrl = @"http://www.vip/app/sendVerifiCode?mobile={0}"; //重新发送验证码
    
        //      2.登入检查验证码
        //接口说明:检查验证码。
        //测试请求地址:http://www.top/app/arRedPacket/toLogin?mobile=18823770014&code=1452
        //正式请求地址:http://www.vip/app/arRedPacket/toLogin?mobile=18823770014&code=1452
    
        private string toLoginUrl = @"http://www.top/app/arRedPacket/toLogin?mobile={0}&code={1}"; //登录接口
        //private string toLoginUrl = @"http://www.vip/app/arRedPacket/toLogin?mobile={0}&code={1}"; //登录接口
    
    
        //public Text mText;
    
        void Start () {
            //SignatureVerify.IsCorrect();
            //mText.text= SignatureVerify.myHash+"签名";
    
            //获取已经储存用户名和验证码
            if (PlayerPrefs.GetString("P_User").ToString() != null)
            {
                InputFieldMobile.text = PlayerPrefs.GetString("P_User").ToString();
                InputFieldVerificationCode.text = PlayerPrefs.GetString("P_Password").ToString();
            }
        }
        
        void Update () {
            
        }
    
       /// <summary>
       /// 计时器开启
       /// </summary>
        void FixedUpdate()
        {
            if (isTiming) //计时开启
            {
                i++;
                if (i > 30)
                {
                    i = 0;
                    NowSecond--; //减
                }
                Btn_Reset.transform.Find("Text").transform.GetComponent<Text>().text = "(" + NowSecond + "s)"+ "<color=#C8C8C8FF>重新发送</color>";
    
                if (NowSecond < 1)
                {
                    isTiming = false; //计时暂停
                    Btn_Reset.transform.Find("Text").transform.GetComponent<Text>().text = "重新获取"; //显示最终按钮
                    Btn_Reset.interactable = true; //按钮设置可用
                }
    
            }
    
    
    
        }
    
        /// <summary>
        /// 登录按钮控制
        /// </summary>
        public void LoginBtn() {
    
    
            if (!CheckPhoneIsAble(InputFieldMobile.text))  //调用检查手机的方法
            {
                InputFieldMobile.text = "";
                InputFieldVerificationCode.text = "";
                promptTxt = "输入的手机格式不对,请重新输入";
                StartCoroutine(DelayHidden());
    
    
            }
            else if (InputFieldVerificationCode.text.Length != 4) //验证码不是4位的判断 包括空少于4位或者超过4位的
            {
                promptTxt = "验证码是4位数,请重新输入";
                StartCoroutine(DelayHidden());
            }
            else {
    
                GetRegStatus_OnGetLoginStatus(InputFieldMobile.text,InputFieldVerificationCode.text);//符合条件 调用登录按钮的接口
            }
            
            
           
        }
        //---------------------------------------------------------登录接口汇编-----------------------------
        /// <summary>
        /// 登录的接口 获取状态码的判断
        /// </summary>
        /// <param name="userLg">手机号</param>
        /// <param name="passwordLg">验证码</param>
        public void GetRegStatus_OnGetLoginStatus(string userLg, string passwordLg)
        {
    
            string url = string.Format(toLoginUrl, userLg, passwordLg); //链接按字符串的格式获取
            StartCoroutine(GetFromUrl_Token(url,
                (v) =>
                {
                    regInfo = "状态码:" + v.code + "    token码:" + v.token + "返回信息提示语:" + v.message; //打印状态信息
                    StatusNumber = v.code; //获取状态码进行赋值
                    tokenCode = v.token; //储存token
               
                    if (StatusNumber == "1") //成功
                    {
                        PlayerPrefs.SetString("P_User", InputFieldMobile.text); //设置手机号来储存
                        PlayerPrefs.SetString("P_Password", InputFieldVerificationCode.text);       //设置验证码储存
                        PlayerPrefs.SetString("mToken", tokenCode); //设置Token储存
                        promptTxt = "正在启动AR红包,请准备开始您的寻宝之旅吧"; //提示语
                        StartCoroutine(DelayHidden()); //开启提示语渐变的过程
                        SceneManager.LoadScene("Main"); //成功之后调入主场景
                        Btn_Login.interactable = false; //设置为不可用
    
                    } //返回状态判断
                    else if (StatusNumber == "0")
                    {
                        InputFieldVerificationCode.text = "";
                        promptTxt = "请输入手机号:";
                        StartCoroutine(DelayHidden());
                    }
                    else if (StatusNumber == "5")
                    {
                        InputFieldVerificationCode.text = "";
                        promptTxt = "验证码错误,请重新输入";
                        StartCoroutine(DelayHidden());
                    }
                    else if (StatusNumber == "8")
                    {
                        InputFieldVerificationCode.text = "";
                        promptTxt = "验证码失效,请重新发送";
                        StartCoroutine(DelayHidden());
                    }
                    else if (StatusNumber == "9")
                    {
                        
                        promptTxt = "请输入验证码";
                        StartCoroutine(DelayHidden());
                    }
                    else
                    {
                        InputFieldVerificationCode.text = "";
                        promptTxt = "服务器内部错误,稍后再试";
                        StartCoroutine(DelayHidden());
                    }
    
                }
                ));
    
        }
    
        /// <summary>
        /// 开启协程获取网络状态  Action没有参数回调 Funtion有参数回调
        /// </summary>
        /// <param name="url"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        IEnumerator GetFromUrl_Token(string url, Action<JsonLogin> callback)
        {
            WWW www = new WWW(url);
            yield return www;
            if (www.isDone && string.IsNullOrEmpty(www.error))
            {
                //Debug.Log(www.text);
                if (null != callback)
                {
                    string jsonStr = www.text.Trim();
                    JsonLogin jd = JsonUtility.FromJson<JsonLogin>(jsonStr);
                    callback.Invoke(jd);
                }
    
    
            }
            else
            {
                Debug.Log("网络错误" + www.error);
                promptTxt = "网络错误,请重新登录";
                DelayHidden();
            }
    
    
        }
    
        //---------------------------------------------------------登录接口汇编完毕-----------------------------
    
            /// <summary>
            /// 开启提示按钮慢慢消失的过程
            /// </summary>
            /// <returns></returns>
        IEnumerator DelayHidden()
        {
            RegProImg.SetActive(true);
            RegProImg.transform.GetChild(0).GetComponent<Text>().text = promptTxt;
            yield return new WaitForSeconds(1.5f);
            Component[] comps = RegProImg.GetComponentsInChildren<Component>();
            foreach (Component c in comps)
            {
                if (c is Graphic)
                {
                    (c as Graphic).CrossFadeAlpha(0, 2, true);
                }
            }
            yield return new WaitForSeconds(1.5f);
            RegProImg.SetActive(false);
        }
    
        /// <summary>
        /// 检查手机是否合法可用 可在可视面板控制输入的是11位
        /// </summary>
        /// <param name="input">输入的手机号</param>
        /// <returns></returns>
        private bool CheckPhoneIsAble(string input)
        {
            if (input.Length < 11)
            {
                return false;
            }
            string dianxin = @"^1[3578][01379]\d{8}$";
            Regex regexDX = new Regex(dianxin);
            string liantong = @"^1[34578][01256]\d{8}";
            Regex regexLT = new Regex(liantong);
            string yidong = @"^(1[012345678]\d{8}|1[345678][012356789]\d{8})$";
            Regex regexYD = new Regex(yidong);
            if (regexDX.IsMatch(input) || regexLT.IsMatch(input) || regexYD.IsMatch(input))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    
        /// <summary>
        /// 点击获取验证码的判断
        /// </summary>
        public void ClickBtnSendReset()
        {
    
            if (!CheckPhoneIsAble(InputFieldMobile.text)) //调用手机号是否合法可用
            {
                promptTxt = "输入的手机格式不对,请重新输入";
                StartCoroutine(DelayHidden());
            }
            else
            {
                NowSecond = 60; //开启60秒倒计时
                isTiming = true; //开启计时
                Btn_Reset.interactable = false; //按钮不可用
                GetRegStatus_OnGetRegStatus(InputFieldMobile.text); //调用回去验证码的接口
            }
    
        }
    
    
        //--------------------------------------------验证码接口---------------------------
        /// <summary>
        /// 调用获取验证码的接口
        /// </summary>
        /// <param name="phoneNum"></param>
        public void GetRegStatus_OnGetRegStatus(string phoneNum)
        {
            string url = string.Format(sendVerifiCodeUrl, phoneNum);
            StartCoroutine(GetFromUrl(url,
                (v) =>
                {
                    regInfo = v.code + "\n" + v.message + "\n";
                    StatusNumber = v.code;
                    if (StatusNumber == "1") 
                    {
                        promptTxt = v.message;
                        StartCoroutine(DelayHidden());
                    }
                    else if (StatusNumber == "0") 
                    {
                        promptTxt = "网络错误,请重新发送....";
                        StartCoroutine(DelayHidden());
                    }
                    else if (StatusNumber == "2") 
                    {
                        promptTxt = "网络错误,请重新发送....";
                        StartCoroutine(DelayHidden());
                    }
    
                }
                ));
    
        }
        IEnumerator GetFromUrl(string url, Action<JsonSend> callback)
        {
            WWW www = new WWW(url);
            yield return www;
            if (www.isDone && string.IsNullOrEmpty(www.error))
            {
                Debug.Log(www.text);
                if (null != callback)
                {
                    string jsonStr = www.text.Trim();
                    JsonSend jd = JsonUtility.FromJson<JsonSend>(jsonStr);
                    callback.Invoke(jd);
                }
            }
            else
            {
                Debug.Log("网络错误" + www.error);
                RegProImg.SetActive(true);
                RegProImg.transform.GetChild(0).GetComponent<Text>().text = "网络错误,请重新登录";
    
            }
    
        }
    
        //--------------------------------------------验证码接口完毕---------------------------
    
    }
    
    

    RedPackCtrl

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class RedPackCtrl : MonoBehaviour
    {
    
        private Ray ray;
        private RaycastHit hit;
    
        void Start()
        {
    
        }
    
    
        void Update()
        {
    
        }
    
    
        /// <summary>
        /// 封装射线
        /// </summary>
        void RaySend()
        {
            if (Input.GetMouseButton(0))
            {
                ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                if (Physics.Raycast(ray, out hit))
                {
                    if (hit.transform.tag == "Red")
                    {
                        GameObject.Find("GoManager").transform.GetComponent<CoinMannger>().InitCoin();
                        Destroy(gameObject);
                    }
                }
    
            }
    
    
        }
    
        /// <summary>
        /// 生成金币的方法
        /// </summary>
        public void InitCoin()
        {
            GameObject.Find("Go").transform.GetComponent<CoinMannger>().InitCoin();
            Destroy(this.transform.gameObject);
        }
    
    }
    
    

    ScreenAdaptation

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class ScreenAdaptation : MonoBehaviour {
    
       /// <summary>
       /// 屏幕适配
       /// </summary>
        void Start()
        {
            float standard_width = 800f;        //初始宽度  
            float standard_height =600f;       //初始高度  
            float device_width = 0f;                //当前设备宽度  
            float device_height = 0f;               //当前设备高度  
            float adjustor = 0f;         //屏幕矫正比例  
            //获取设备宽高  
            device_width = Screen.width;
            device_height = Screen.height;
            //计算宽高比例  
            float standard_aspect = standard_width / standard_height;
            float device_aspect = device_width / device_height;
            //计算矫正比例  
            if (device_aspect < standard_aspect)
            {
                adjustor = standard_aspect / device_aspect;
            }
    
            CanvasScaler canvasScalerTemp = transform.GetComponent<CanvasScaler>(); //获取UI下的组件
            if (adjustor == 0)
            {
                canvasScalerTemp.matchWidthOrHeight = 0; //注意数值
            }
            else
            {
                canvasScalerTemp.matchWidthOrHeight = 1; //注意数值
            }
    
    
        }
      
        
    
        void Update () {
            
        }
    }
    
    

    SignatureVerify

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /// <summary>  
    /// Signature verify tool class  
    /// 防止被二次签名重打包  
    /// </summary>  
    public class SignatureVerify  {
    
        /** 
             * Verify the signature is correct 
             **/
    
        internal static int myHash = 0;
        public static bool IsCorrect()
        {
    #if UNITY_ANDROID
            // 获取Android的PackageManager      
            AndroidJavaClass Player = new AndroidJavaClass("com.unity3d.player.UnityPlayer");  
            AndroidJavaObject Activity = Player.GetStatic<AndroidJavaObject>("currentActivity");  
            AndroidJavaObject PackageManager = Activity.Call<AndroidJavaObject>("getPackageManager");  
              
            // 获取当前Android应用的包名  
            string packageName = Activity.Call<string>("getPackageName");  
              
            // 调用PackageManager的getPackageInfo方法来获取签名信息数组      
            int GET_SIGNATURES = PackageManager.GetStatic<int>("GET_SIGNATURES");  
            AndroidJavaObject PackageInfo = PackageManager.Call<AndroidJavaObject>("getPackageInfo", packageName, GET_SIGNATURES);  
            AndroidJavaObject[] Signatures = PackageInfo.Get<AndroidJavaObject[]>("signatures");  
              
            // 获取当前的签名的哈希值,判断其与我们签名的哈希值是否一致  
            if (Signatures != null && Signatures.Length > 0)  
            {  
                int hashCode = Signatures[0].Call<int>("hashCode");  
                myHash = hashCode;  
                return hashCode == -1705791141;//我们签名的哈希值  
                  
            }  
            return false;  
    #else
            return true;
    #endif
        }
    }
    
    

    三、效果展示

    相关文章

      网友评论

      • 冰絮语:你好,有源码可以下载吗
        TonyWan_AR:@冰絮语 文章已经有源码了,工程的话私聊

      本文标题:AR开发实战Vuforia项目之AR寻宝(实现与服务器对接功能)

      本文链接:https://www.haomeiwen.com/subject/sqgrzxtx.html