美文网首页
AR开发实战Vuforia项目之PokemonGo(二、基于Lb

AR开发实战Vuforia项目之PokemonGo(二、基于Lb

作者: TonyWan_AR | 来源:发表于2018-07-26 17:32 被阅读465次

    一、框架视图

    二、关键代码

    1、AR

    AR_Au

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class AR_Au : MonoBehaviour {
    
        public static AR_Au Instance; //单例模式
    
        private AudioSource AuS; //对声音持有引用
    
    
         void Awake()
        {
            Instance = this;//单例模式 赋值    
        }
    
        void Start () {
    
            AuS = gameObject.transform.GetComponent<AudioSource>(); //声音组件赋值
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 播放声音的事件函数
        /// </summary>
        public void BtnAuPlay() {
    
            AuS.Play();
        }
    }
    
    

    AR_UIMgr

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using UnityEngine.UI;
    
    public class AR_UIMgr : MonoBehaviour {
    
        public static AR_UIMgr Instance; //单例模式
    
        public Text Tx_BallNum; //储存显示精灵球数量的Text组件
    
        public Text Tx_FoodNum; //储存显示食物数量的Text组件
    
        public GameObject PnCatch; //小精灵捕捉成功的面板
    
        public Text InputPetName;//输入精灵名字的组件
    
        private void Awake()
        {
            Instance = this; //单例模式
        }
    
        void Start () {
            
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 返回地图按钮事件
        /// </summary>
        public void Btn_GoMapScn() {
    
            AR_Au.Instance.BtnAuPlay();//声音播放事件
            SceneManager.LoadScene("PKGOMain");
        }
    
        /// <summary>
        /// 刷新精灵球的数量事件
        /// </summary>
        public void UpdateUIBallNum() {
    
            Tx_BallNum.text = StaticData.BallNum.ToString();    //把精灵球数量的全集数据显示在UI中
        }
    
    
        /// <summary>
        /// 刷新食物的数量事件
        /// </summary>
        public void UpdateUIFoodNum() {
    
            Tx_FoodNum.text = StaticData.FoodNum.ToString(); //把食物数量的全局数据显示在UI中 
        }
    
    
    
        /// <summary>
        /// 显示小精灵的捕捉成功的面板
        /// </summary>
        public void Show_PnCatch() {
    
            PnCatch.SetActive(true);
        }
    
    
        /// <summary>
        /// 捕捉小精灵的确认按钮
        /// </summary>
        public void Btn_Yes() {
    
            AR_Au.Instance.BtnAuPlay();//点击按钮的特效事件
    
            //Debug.Log("输入的名字:"+InputPetName.text);
            string _name = InputPetName.text; //从输入框获取小精灵的名字
    
            int _index = StaticData.CatchingPetIndex; //从全局脚本中获取正在捕捉小精灵在预制体集合中的序号
    
            StaticData.AddPet(new PetSave(_name,_index));//从全局数据的小精灵列表中添加一条小精灵属性类数据
    
            SceneManager.LoadScene("Store_Scn"); //跳转到仓库场景
        }
    
    
        /// <summary>
        /// 放生按钮的函数
        /// </summary>
        public void Btn_GiveUp() {
    
            AR_Au.Instance.BtnAuPlay();//播放放生按钮的声效
            SceneManager.LoadScene("PKGOMain"); //跳回地图场景
        }
    
    
        /// <summary>
        /// 进入仓库的按钮
        /// </summary>
        public void Btn_ToStore() {
    
            AR_Au.Instance.BtnAuPlay(); //播放进去仓库的声效
            SceneManager.LoadScene("Store_Scn"); //进入仓库场景
        }
    
    
    
    
    }
    
    

    ARBallCtrl

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ARBallCtrl : MonoBehaviour {
    
    
        public static ARBallCtrl Instance; //单例模式
    
        public Transform PosInsBall;    //储存生成精灵球的位置
    
        private GameObject[] balls; //储存精灵球的预制体
    
    
        private void Awake()
        {
            Instance = this; //单例模式
        }
    
        void Start () {
    
            balls = Resources.LoadAll<GameObject>("Balls");
    
            AR_UIMgr.Instance.UpdateUIBallNum(); //刷新精灵球的数量
    
            InsNewBall(); //执行测试下
    
            //PosInsBall.transform.parent.transform.localRotation = Quaternion.identity; //默认相机不能旋转
    
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 生成精灵球
        /// </summary>
        public void InsNewBall() {
    
            if (StaticData.BallNum>0) //只有大于0 的情况下 才执行实例化精灵球
            {
                GameObject _ball = Instantiate(balls[0], PosInsBall.position, PosInsBall.rotation); //实例化精灵球
                _ball.transform.SetParent(PosInsBall); //设置精灵球的父级物体 为了保证发射前在屏幕的固定位置
                _ball.gameObject.AddComponent<SphereCollider>();    //给球体增加球型碰撞器
                _ball.gameObject.GetComponent<SphereCollider>().radius = 0.01f; //设置碰撞触发器半径的大小
               // _ball.gameObject.AddComponent<ARShootBall>(); //添加发射球的控制脚本
    
                _ball.gameObject.transform.localScale = new Vector3(25f, 25f, 25f); //原预制体不变 动态改变尺寸的大小 缩放比例
    
            }
           
        }
    
    
    
    }
    
    

    ARFoodCtrl

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ARFoodCtrl : MonoBehaviour {
    
        public static ARFoodCtrl Instance;      //单例模式
    
        public Transform PosInsFood; //储存生成食物的位置
    
        private GameObject[] foods; //储存食物的预制体
    
    
        void Awake()
        {
            Instance = this;
        }
    
    
        void Start () {
    
            foods = Resources.LoadAll<GameObject>("Foods"); //加载所有的食物
    
            AR_UIMgr.Instance.UpdateUIFoodNum(); //刷新食物的数量
    
        }
        
    
        void Update () {
            
        }
    
        /// <summary>
        /// 生成新的食物
        /// </summary>
        public void InsNewFood() {
    
    
            if (StaticData.FoodNum>0) //如果食物大于0 的话才生成
            {
    
            }
        }
    }
    
    

    ARInsPets

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ARInsPets : MonoBehaviour {
    
        public Transform[] traPos; //储存预制体的位置
    
        private GameObject[] pets;//储存所有的精灵预制体
    
        public Transform CameraTra;//AR摄像机的位置
    
        void Start () {
    
            pets = Resources.LoadAll<GameObject>("Pets"); //加载所有的精灵预制体
    
            InsPet();//生成捕捉小精灵
    
            checkDis(); //检查距离
        }
        
    
    
    
        
        void Update () {
            
        }
    
        /// <summary>
        /// 生成精灵
        /// </summary>
        public void InsPet() {
    
            int _index = Random.Range(0,traPos.Length); //随机位置
    
            Transform _tra = traPos[_index]; //得到随机位置
    
            GameObject _pet=Instantiate(pets[StaticData.CatchingPetIndex],_tra.position,_tra.rotation);   //实例化随机生成的位置上的小精灵 注意预制体数组的位置
    
            _pet.transform.localScale = new Vector3(0.5f,0.5f,0.5f); //生成的预制体可以缩小到0.5倍
    
            Debug.Log("生成小精灵的名字:::;" +_pet.name);
    
            _pet.transform.LookAt(new Vector3(CameraTra.position.x,_pet.transform.position.y,CameraTra.position.z)); //让生成的小精灵面朝玩家
    
           
        }
    
        /// <summary>
        /// 检查每个生成小精灵的预支点到摄像机的距离
        /// </summary>
        private void checkDis() {
    
            foreach (Transform pos in traPos)
            {
                float _dis = Vector3.Distance(pos.position,CameraTra.position);
                Debug.Log("检查预支点和摄像机的距离:"+_dis);
            }
        }
    }
    
    

    ARShootBall

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ARShootBall : MonoBehaviour {
    
        public float FwdForce = 200f; //设置给小球向前的力的大小
    
        public Vector3 StanTra = new Vector3(0,1f,0);   //设置夹角的参照数值
    
        private bool blTouched = false;//判断手指是否触碰了精灵球的位置
    
        private bool blShooted = false;//判断精灵球是否可以发射
    
        private Vector3 startPosition; //手指滑动的起始点
    
        private Vector3 endPosition;    //手指滑动的终点
    
        private float disFick; //记录手指滑动的距离
    
        private Vector3 offset; //记录手指的偏移量
    
        private int timeFick;   //用帧数来记录手指滑动的时间
    
        private float speedFick;//记录滑动的速度
    
        private Camera camera;//记录主摄像机
    
        void Start () {
    
            camera = Camera.main; //给主摄像机赋值
        }
        
    
        void Update () {
    
            if (blTouched) //如果按在小球上 允许计算手指滑动
            {
                slip();
            }
        }
    
        /// <summary>
        /// 重置参数
        /// </summary>
        private void resetVari() {
    
            startPosition = Input.mousePosition; // 起始位置设置为手指按下的位置
    
            endPosition = Input.mousePosition;  //终点位置设置为手指按下的位置
    
    
        }
    
        /// <summary>
        /// 鼠标(手指)按下 (是否触碰到脚本挂载的物体)
        /// </summary>
        private void OnMouseDown()
        {
            if (blShooted==false) //精灵球尚未发射
            {
                blTouched = true;//允许检测手指滑动
            }
        }
    
    
        /// <summary>
        /// 计算手指滑动的距离
        /// </summary>
        private void slip() {
    
            timeFick += 25; //时间每帧增加25  通过测试得出的数值
    
            if (Input.GetMouseButtonDown(0)) //当手指按下的时候
            {
                resetVari();    //重置参数
            }
    
            if (Input.GetMouseButton(0)) //当手指一直持续按在屏幕的时候
            {
                endPosition = Input.mousePosition;//把手指的终点位置变量 赋值刷新为当前手指所处的位置
                offset = camera.transform.rotation * (endPosition-startPosition);//获取手指在世界坐标的偏移向量
                disFick = Vector3.Distance(startPosition,endPosition);//计算手指滑动的距离
            }
    
            if (Input.GetMouseButtonUp(0)) //当手指抬起的时候
            {
                speedFick = disFick / timeFick; //计算滑动的速度
                blTouched = false;//手指是否触碰到精灵球 设置为否
                timeFick = 0;//时间记录为零
                if (disFick>20&&endPosition.y-startPosition.y>0)  //r如果手指一动距离大于20 并且方向是向上滑动  防止误碰精灵球而让精灵球消失
                {
                    shootBall(); //发射精灵球
                }
    
    
            }
        }
    
    
        /// <summary>
        /// 发射精灵球
        /// </summary>
        private void shootBall() {
    
            transform.gameObject.AddComponent<Rigidbody>(); //精灵球添加刚体
            Rigidbody _rigBall = transform.GetComponent<Rigidbody>(); //获取刚体的组件
            //_rigBall.velocity = offset * 0.003f * speedFick; //给刚体添加一个速度
            _rigBall.velocity = offset.normalized * speedFick; //normalized只获取向量的方向 没有值
            _rigBall.AddForce(camera.transform.forward*FwdForce); //给摄像机位置一个向前的力
            _rigBall.AddTorque(transform.right); //添加转矩  就是让精灵球旋转起来 有动态的感觉
            _rigBall.drag = 0.5f;//设置角阻力
            blShooted = true;//已经发射 表示在拖动精灵球 不可能有发射的效果了
            transform.parent = null; //脱离父级物体 设置父类为空 可以自由活动 免得不在偏移
    
            StaticData.BallNum--; //发射之后数量减一
            AR_UIMgr.Instance.UpdateUIBallNum(); //更新精灵球的数量在UI中的显示
    
    
            //ARBallCtrl.Instance.InsNewBall(); //单例 生成新的精灵球
            StartCoroutine(LateInsBall()); //开启延迟生成精灵球的函数
    
            Destroy(_rigBall.transform.gameObject,5f); //5秒之后销毁发射的精灵球 
            //Debug.Log("是否销毁精灵球?");
    
        }
    
    
        /// <summary>
        /// 延迟重新生成精灵球 
        /// </summary>
        /// <returns></returns>
        IEnumerator LateInsBall() {
    
            yield return new WaitForSeconds(0.2f);  //延迟0.2秒
            ARBallCtrl.Instance.InsNewBall(); //单例模式  生成心的精灵球
    
        }
    
    
    
    
      
    
    }
    
    
    2、Login

    Login_Au

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Login_Au : MonoBehaviour {
    
        public static Login_Au Instance; //单例模式
    
        private AudioSource AuS; //控制登录的声音
    
        void Awake()
        {
            Instance = this;//单例模式赋值
        }
    
    
        void Start () {
    
            AuS = gameObject.transform.GetComponent<AudioSource>();
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 播放登录声音的事件
        /// </summary>
        public void BtnAuPlay() {
    
            AuS.Play();
        }
    
    }
    
    

    Login_UI

      using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class Login_UI : MonoBehaviour {
    
    
        void Start () {
            
        }
        
    
        void Update () {
            
        }
    
        /// <summary>
        /// 登录地图场景
        /// </summary>
        public void Btn_ToMap() {
    
            Login_Au.Instance.BtnAuPlay();  //播放登录的声效
            SaveAndLoad.Load(); //静态读取全局数据的方法 在声音后面执行
            SceneManager.LoadScene("PKGOMain"); //跳转到地图场景
        }
    
    
    }
    
    3、Map
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Ball_Find : MonoBehaviour {
    
    
        void Start () {
            
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 触发器检测
        /// </summary>
        /// <param name="coll"></param>
        private void OnTriggerEnter(Collider coll)
        {
            if (coll.tag=="Avatar")  //触发器 检测到标签是“Avatar” 则
            {
                UI_Mgr_02.Instance.AddBallNum(); //调用单例模式增加精灵球的数量
                Destroy(gameObject); //精灵球消失
            }
        }
    
    }
    
    

    BoyCtrl

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /// <summary>
    /// 脚本挂在主角上
    /// </summary>
    public class BoyCtrl : MonoBehaviour {
    
        private Animator mAnimator;
        //定义动画控制器
    
    
        private MoveAvatar mMoveAvatar;
        //储存角色的移动类 为了获取角色移动的状态
    
    
        void Start () {
    
    
            mAnimator = gameObject.transform.GetComponent<Animator>();
            //给动画状态机赋值 获取角色控制器的组件
    
            mMoveAvatar = gameObject.transform.parent.GetComponent<MoveAvatar>();
            //给移动类赋值 父类上的组件 获取移动的状态类 获取父父物体上的角色控制器的角色移动类
    
            
        }
        
        
        void Update () {
    
            if (mMoveAvatar.animationState==MoveAvatar.AvatarAnimationState.Idle) // 枚举  如果是动画状态机中角色动画状态是定义中的待机状态 则
            {
    
                if (!mAnimator.GetCurrentAnimatorStateInfo(0).IsName("Idle")) //如果当前播放动画不是 待机状态  则设置 触发当前的待机动画 注意前面是 非 感叹号
                {
                    mAnimator.SetTrigger("Idle"); //触发动画状态机中的待机动画
                }
    
            }
            else if (mMoveAvatar.animationState==MoveAvatar.AvatarAnimationState.Walk) //如果是动画状态机中角色的状态是定义中的走路状态 则
            {
    
                if (!mAnimator.GetCurrentAnimatorStateInfo(0).IsName("Walk")) //如果当前播放的动画不是行走 则设置 触发当前行走的动画 注意加感到好 非 布尔值
                {
                    mAnimator.SetTrigger("Walk"); //触发动画状态机中的走路动画
                }
               
            }
            else if (mMoveAvatar.animationState==MoveAvatar.AvatarAnimationState.Run) //如果是动画状态机中角色的状态是定义中的跑步状态 则
            {
                if (!mAnimator.GetCurrentAnimatorStateInfo(0).IsName("Run")) //如果当前播放的动画不是跑步 则设置 触发当前跑步的动画  注意非  布尔值
                {
                    mAnimator.SetTrigger("Run"); //触发动画状态机中的跑步动画
                }
             
            }
    
    
        }
    }
    
    

    DynamicLoadEvent

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using GoShared;
    
    public class DynamicLoadEvent : MonoBehaviour {
    
    
        public GameObject InsCube; //动态加载放置进地图的3D盒子
    
        void Start () {
            
        }
        
        
        void Update () {
            
        }
    
    
        /// <summary>
        /// 把u3d的位置转化为经纬度坐标
        /// </summary>
        public void CheckPosition()
        {
            GameObject _avatar = GameObject.FindGameObjectWithTag("Avatar"); //查到角色游戏对象
    
            Vector3 _avatarV3 = _avatar.transform.position; //获取游戏对象的当前位置
    
            Coordinates _coordinates = Coordinates.convertVectorToCoordinates(_avatarV3); //通过Vector3类型的坐标 转化成经纬度坐标
    
            Debug.Log("纬度 Avatar Latitude:" + _coordinates.latitude + "经度:Avatar Longitude:" + _coordinates.longitude);
            //把转化好的经纬度显示在控制台上
    
        }
    
        /// <summary>
        /// 动态加载 盒子
        /// </summary>
        public void SetCube()
        {
    
            Coordinates _coordinates = new Coordinates(22.5780563, 113.8649978, 0); //设置好经纬度  参数1:纬度 参数2:经度 参数3:默认为 0
            
            Vector3 _v3 = _coordinates.convertCoordinateToVector(0); //把经纬度转化成游戏中的坐标
    
            GameObject _cube = Instantiate(InsCube); //生成预制体盒子
    
            _cube.transform.position = _v3; //设置盒子的位置
    
    
    
        }
    
    
    
    }
    
    

    Food_Find

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Food_Find : MonoBehaviour {
    
    
        void Start () {
            
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 食物触发事件
        /// </summary>
        /// <param name="coll"></param>
        private void OnTriggerEnter(Collider coll)
        {
            if (coll.tag=="Avatar") //如果检测到人的出触发器 
            {
                UI_Mgr_02.Instance.AddFoodNum();    //则调用单例模式中食物增加的方法
                Destroy(gameObject); //食物消失
            }
        }
    }
    
    

    InsPets

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class InsPets : MonoBehaviour {
    
        public  GameObject[] Pets;
    
        //游戏启动时候加载所有的精灵资源
        void Awake()
        {
            Pets = Resources.LoadAll<GameObject>("Pets"); //参数1:加载资源的类型 参数2:文件下的路径
        }
    
        void Start () {
    
            InsPet();//生成小精灵
    
        }
        
    
        void Update () {
            
        }
    
    
        /// <summary>
        /// 生成随机精灵的函数
        /// </summary>
        private void InsPet() {
    
            int _petIndex = Random.Range(0,Pets.Length); //随机生成一个精灵的下标序列号  序列号从0到所有小精灵的预制体数量中  随机选择
    
            Instantiate(Pets[_petIndex],transform.position,transform.rotation);  //实例化 生成小精灵
    
        }
    }
    
    
    

    InsPoint

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class InsPoint : MonoBehaviour {
    
        //公有变量首字母大写
        public GameObject Ava; //储存地图的角色
    
        public GameObject PrePoint; //储存事件点的预制体
    
        public float MinDis = 10f; //储存最小距离范围值 3米
    
        public float MaxDis = 50f;//储存最大距离范围 50米
    
        //私有变量首字母小写
        private Vector3 v3Ava; //储存当前的角色的坐标位置
    
    
        
        void Start () {
            
        }
        
        
        void Update () {
            
        }
    
    
        /// <summary>
        /// 随机生成预制体的方法 生成精灵的方法 随机一段距离然后获取距离的坐标位置信息
        /// </summary>
        public void InsPointFun() {
    
            Map_Au.Instance.BtnAuPlay();    //播放生成精灵的声效
    
            v3Ava = Ava.transform.position;//获取角色的当前位置的坐标信息
    
            float _dis = Random.Range(MinDis,MaxDis); //获取随机位置的信息 从最小距离到最大距离之间取一个随机值  局部变量  首写加下划线“_”
    
            Vector2 _pOri = Random.insideUnitCircle; //从原点(0,0)的坐标上随机获取一个任意方向的向量
    
            Vector2 _pNor = _pOri.normalized; //获取到向量单位的向量 只有方向,大小为1; 有方向 有值才能称为向量
    
            Vector3 v3Point = new Vector3(v3Ava.x+_pNor.x*_dis,2.5f,v3Ava.z+_pNor.y*_dis); //算出随机点的位置 因为值为1,所以要乘距离值 _pNor.x*_Dis随即向量的X值  _pNor.y*Dis随即向量的Y值; Y值取决要生成的游戏对象的大小
    
            GameObject _pointMark = GameObject.Instantiate(PrePoint,v3Point,transform.rotation); //实例化游戏物体  参数1:预制体 参数2:位置坐标信息  参数3:旋转方向为当前物体的旋转方向
        }
    }
    
    

    Map_Au

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Map_Au : MonoBehaviour {
    
        public static Map_Au Instance;  //单例模式
    
        private AudioSource AuS; //定义声音的组件
    
        void Awake()
        {
            Instance = this; //单例模式     
        }
    
        void Start () {
    
            AuS = gameObject.transform.GetComponent<AudioSource>(); //声音组件的持有引用
        }
        
    
        void Update () {
            
        }
    
        /// <summary>
        /// 播放点击按钮的事件
        /// </summary>
        public void BtnAuPlay() {
    
            AuS.Play();
    
        }
    }
    
    

    MobileGyro

    using UnityEngine;
    using System.Collections;
    //摄像机  陀螺仪转动
    public class MobileGyro : MonoBehaviour
    {
        Gyroscope gyro;
        Quaternion quatMult;
        Quaternion quatMap;
        GameObject player;
        GameObject camParent;
        void Awake()
        {
            player = GameObject.Find("Player");
            // find the current parent of the camera's transform
            Transform currentParent = transform.parent;
            // instantiate a new transform
            camParent = new GameObject("camParent");
            // match the transform to the camera position
            camParent.transform.position = transform.position;
            // make the new transform the parent of the camera transform
            transform.parent = camParent.transform;
            // make the original parent the grandparent of the camera transform
            //camParent.transform.parent = currentParent;
            // instantiate a new transform
            GameObject camGrandparent = new GameObject("camGrandParent");
            // match the transform to the camera position
            camGrandparent.transform.position = transform.position;
            // make the new transform the parent of the camera transform
            camParent.transform.parent = camGrandparent.transform;
            // make the original parent the grandparent of the camera transform
            camGrandparent.transform.parent = currentParent;
    
            Input.gyro.enabled=true;
            gyro = Input.gyro;
    
            gyro.enabled = true;
            camParent.transform.eulerAngles = new Vector3(90,-135, 0);
           //camParent.transform.eulerAngles = new Vector3(90, 0, 180);
            //quatMult = new Quaternion(0, 0, 1, 0);
            quatMult = new Quaternion(0, 0, 1, 0);
        }
    
        void Update()
        {
    
            quatMap = new Quaternion(gyro.attitude.x, gyro.attitude.y, gyro.attitude.z, gyro.attitude.w);
            Quaternion qt=quatMap * quatMult;
    
            transform.localRotation =qt;
    
        }
    
    }
    

    MoveEffect

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /// <summary>
    /// 浮动旋转的脚本
    /// </summary>
    public class MoveEffect : MonoBehaviour {
    
        private float radian = 0; //起始的弧度
    
        private float perRad = 0.03f;//弧度的变化值
    
        private float add = 0;  //储存位置的偏移量
    
        private Vector3 posOri;//储存物体生成时的真实坐标
        
        void Start () {
    
            posOri = transform.position;//把物体生成时的位置坐标信息记录下来
        }
        
        
        void Update () {
    
            //radian += perRad;//弧度不断增加
    
            //add = Mathf.Sin(radian); //得到弧度的偏移值
    
            //transform.position = posOri + new Vector3(0,add,0);//让物体不断浮动起来
    
    
            //transform.Rotate(0, Time.deltaTime * 25f,0,Space.World); //以世界坐标为旋转依据  在Y轴上进行旋转
    
            MoveEffeftFunc();
        }
    
        /// <summary>
        /// 让物体旋转上下浮动的效果
        /// </summary>
        private void MoveEffeftFunc() {
    
            radian += perRad;//弧度不断增加
    
            add = Mathf.Sin(radian); //得到弧度的偏移值
    
            transform.position = posOri + new Vector3(0, add, 0);//让物体不断浮动起来
    
    
            transform.Rotate(0, Time.deltaTime * 25f, 0, Space.World); //以世界坐标为旋转依据  在Y轴上进行旋转
        }
    }
    
    

    Pet_Find

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Pet_Find : MonoBehaviour {
    
        public int Pet_Index;   //储存小精灵的序列号
        
        void Start () {
    
            if (GameObject.FindGameObjectWithTag("Avatar"))
            {
                gameObject.transform.LookAt(GameObject.FindGameObjectWithTag("Avatar").transform); //让精灵一开始朝向主角
            }
                
            
                      
        }
        
    
        void Update () {
            
        }
    
    
        /// <summary>
        /// 发现宠物的触发器检测
        /// </summary>
        /// <param name="coll">触发物体</param>
        private void OnTriggerEnter(Collider coll)
        {
            if (coll.tag=="Avatar") //如果检测到的物体是 主角则 设置捕捉面板的状态
            {
                UI_Mgr_02.Instance.SetIm_Catch(true); //显示捕捉面板
                UI_Mgr_02.Instance.Tx_PetName.text = StaticData.GetType(Pet_Index); //通过输入序号赋值字符串给精灵的名称
                StaticData.CatchingPetIndex = Pet_Index;//当碰到角色时 把小精灵的序列号赋值给静态数据中正要捕捉的小精灵序号
                Destroy(gameObject); //销毁精灵
    
            }
    
            if (coll.tag=="Ball")
            {
              //  Debug.Log("击中小精灵了····");
                playCatched(); //播放动画
                StartCoroutine(ShowCatchPn()); //开启延迟显示成功捕捉的画面
            }
        }
    
        /// <summary>
        /// 延迟显示成功捕捉面板并销毁小精灵
        /// </summary>
        /// <returns></returns>
        IEnumerator ShowCatchPn() {
    
            yield return new WaitForSeconds(2f);
             AR_UIMgr.Instance.Show_PnCatch();   //显示捕捉成功面板
            Destroy(transform.gameObject);//销毁小精灵本身
        }
    
        /// <summary>
        /// 播放被捉到的画面  私有函数首字母小写
        /// </summary>
        private void playCatched() {
            transform.GetComponent<Animator>().SetTrigger("Catched");
        }
    
    }
    
    
    
    

    PointEvent

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 随机生成点事件
    /// </summary>
    public class PointEvent : MonoBehaviour {
    
        // public GameObject Pet; //储存小精灵的预制体
        public GameObject[] Pets; 
    
        //public GameObject Ball; //储存精灵球的预制体
        public GameObject[] Balls;
    
    
        //public GameObject Food; //储存食物的预制体
        public GameObject[] Foods;
    
    
        /// <summary>
        /// 动态加载食物 和精灵球  可以考虑用asssetbundle
        /// </summary>
         void Awake()
        {
            Pets = Resources.LoadAll<GameObject>("Pets"); //参数1:加载资源的类型 参数2:文件下的路径
            Balls = Resources.LoadAll<GameObject>("Balls"); //加载所有的精灵球
            Foods = Resources.LoadAll<GameObject>("Foods"); // 加载所有的食物
    
        }
    
    
    
    
        void Start () {
            //申请局部变量 随机生成事件
            int _randomEvent = Random.Range(0,3);
            if (_randomEvent==0)
            {
                InsPet();
            }
            else if (_randomEvent==1)
            {
                InsBall();
            }
            else if (_randomEvent==2)
            {
                InsFood();
            }
    
    
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 生成小精灵
        /// </summary>
        private void InsPet() {
    
            int _petIndex = Random.Range(0, Pets.Length); //随机生成一个精灵的下标序列号  序列号从0到所有小精灵的预制体数量中  随机选择
       
           GameObject _pet= Instantiate(Pets[_petIndex], transform.position, transform.rotation);  //实例化 生成小精灵
                                                                                                   // Instantiate(Pet,transform.position,transform.rotation);
    
            _pet.transform.GetComponent<Pet_Find>().Pet_Index = _petIndex; //把生成的小精灵的序号传递给小精灵身上挂在的脚本
        }
    
        /// <summary>
        /// 生成精灵球
        /// </summary>
        private void InsBall() {
    
            int _ballIndex = Random.Range(0,Balls.Length);
           // Debug.Log("精灵球的下标:::::::::" + _ballIndex);
            GameObject _ball= Instantiate(Balls[_ballIndex], transform.position + new Vector3(0,5f,0),transform.rotation); //Y轴上面偏移5f距离
    
            //Debug.Log("精灵球的名称:::::::::" + _ball.name); //精灵球碰撞器太大·导致数量直接增加
            _ball.transform.localEulerAngles = new Vector3(-30,0,0); //围绕X轴旋转了-30度
    
            _ball.AddComponent<SphereCollider>(); //增加碰撞器组件
            _ball.GetComponent<SphereCollider>().isTrigger = true; //设置为触发器
            _ball.GetComponent<SphereCollider>().radius = 0.01f; //设置碰撞器的半径  注意半径的大小
            _ball.AddComponent<Rigidbody>();//添加刚体
            _ball.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;//冻结刚体上所有物理的转换效果
            _ball.AddComponent<MoveEffect>(); //添加运动特效的脚本
            _ball.AddComponent<Ball_Find>();    //添加发现精灵球的脚本
    
        }
    
        /// <summary>
        /// 生成食物
        /// </summary>
        private void InsFood() {
            int _foodIndex = Random.Range(0,Foods.Length);
           GameObject _food=Instantiate(Foods[_foodIndex],transform.position+new Vector3(0,5f,0),transform.rotation);//Y轴上偏移5f的距离
    
            _food.AddComponent<BoxCollider>();  //增加碰撞器组件
            _food.GetComponent<BoxCollider>().isTrigger = true; //设置为触发器
            _food.GetComponent<BoxCollider>().center = new Vector3(0,0f,0);     //设置中心点的位置
            _food.GetComponent<BoxCollider>().size = new Vector3(0.33f,0.3f,0.33f); //设置碰撞器的大小尺寸
            _food.AddComponent<Rigidbody>();//添加刚体
            _food.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll; //冻结刚体所有物体的转换
            _food.AddComponent<MoveEffect>();   //添加运动特效的脚本
            _food.AddComponent<Food_Find>();    //添加找到食物的脚本
    
    
        }
    
    
    
    
    
    }
    
    

    UI_Mgr_02

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;
    
    public class UI_Mgr_02 : MonoBehaviour {
    
        //单例模式
        public static UI_Mgr_02 Instance;
    
    
        public Text Tx_BallNum; //储存精灵球的数量
    
        public Text Tx_FoodNum; //储存食物的数量
    
        public GameObject Im_Catch; //储存捕捉面版
    
    
        public Text Tx_PetName; //储存精灵的名称 
    
         void Awake()
        {
            Instance = this;   
        }
    
         void Start()
        {
            Tx_BallNum.text = StaticData.BallNum.ToString();// 一开始调用全局变量中的精灵球数量在UI中的显示
    
            Tx_FoodNum.text = StaticData.FoodNum.ToString();    // 一开始调用全局变量中的 食物数量在UI中的显示
        }
    
    
        /// <summary>
        /// 增加精灵球的数量
        /// </summary>
        public void AddBallNum() {
    
            //int _num = int.Parse(Tx_BallNum.text); //将字符串转变成整型
    
            //_num++; //数量加加
    
            //Tx_BallNum.text = _num.ToString(); //文本赋值
    
            StaticData.BallNum++; //精灵球+1
    
            Tx_BallNum.text = StaticData.BallNum.ToString(); //显示精灵球数量
    
    
        }
    
        /// <summary>
        /// 增加食物的数量
        /// </summary>
        public void AddFoodNum() {
    
            //int _num = int.Parse(Tx_FoodNum.text);  //将字符串转换成整型
    
            //_num++; //数量加加
    
            //Tx_FoodNum.text = _num.ToString(); //数字转换成字符串 赋值
    
            StaticData.FoodNum++; //食物+1;
    
            Tx_FoodNum.text = StaticData.FoodNum.ToString(); //显示食物的数量
    
    
        }
    
        /// <summary>
        /// 设置捕捉面板的激活状态
        /// </summary>
        /// <param name="bl"></param>
        public void SetIm_Catch(bool bl) {
            Map_Au.Instance.BtnAuPlay(); //跳转的声效
            Im_Catch.SetActive(bl); //通过参数来控制面板是隐藏还是显示  参数是布尔类型
        }
    
    
        /// <summary>
        /// 跳转到Ar场景
        /// </summary>
        public void Btn_GoARScn() {
            Map_Au.Instance.BtnAuPlay(); //跳转的声效
            SceneManager.LoadScene("Ar_Scn");
        }
    
        /// <summary>
        /// 跳转到仓库场景
        /// </summary>
        public void Btn_ToStore() {
    
            Map_Au.Instance.BtnAuPlay();//跳转到仓库的声效
            SceneManager.LoadScene("Store_Scn");
        }
    
    
    }
    
    
    4、Pet

    PetSave

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PetSave  {
    
        private string petName = "未命名宠物";  //记录小精灵的名字
    
        private int petIndex = 0;//记录小精灵在对应的模型在集合中对应的序列号
    
    
        /// <summary>
        /// 精灵名字的属性
        /// </summary>
        public string PetName {
            get { return petName; }
            set { petName = value; }
        }
    
    
        /// <summary>
        /// 精灵序列号属性
        /// </summary>
        public int PetIndex
        {
            get { return petIndex; }
            set { petIndex = value; }
    
        }
    
    
    
        /// <summary>
        /// 带参数的构造函数
        /// </summary>
        /// <param name="name">精灵名字的参数</param>
        /// <param name="index">精灵序列号</param>
        public PetSave(string  name,int index) {
    
            PetName = name;  //名字属性赋值
    
            PetIndex = index;   //序列号属性赋值
        }
    
    
    
    
    }
    
    
    5、Static

    SaveAndLoad

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 静态调用数据类
    /// </summary>
    public static class SaveAndLoad {
    
    
        /// <summary>
        /// 保存数据
        /// </summary>
        public static void Save() {
    
            ES3.Save<int>("BallNum", StaticData.BallNum); //保存精灵球的数量
    
            ES3.Save<int>("PetNum",StaticData.PetList.Count); //保存已经捕捉小精灵的数量
    
            //保存每个已被捕捉精灵的相关信息
            for (int i = 0; i < StaticData.PetList.Count; i++)
            {
    
                ES3.Save<string>("PetNm" + i.ToString(), StaticData.PetList[i].PetName);
                ES3.Save<int>("PetIndex" + i.ToString(), StaticData.PetList[i].PetIndex);
            }
        }
    
    
    
        /// <summary>
        /// 读取数据
        /// </summary>
        public static void Load() {
            
            if (ES3.KeyExists("BallNum")&&ES3.KeyExists("PetNum")) //先判断它是否存在
            {
                StaticData.BallNum = ES3.Load<int>("BallNum");  //读取精灵球的数量赋值给全局变量中
    
                int _petNum = ES3.Load<int>("PetNum"); //读取到已经捕捉到的精灵球数量
    
                //把存在的小精灵都赋值
                for (int i = 0; i <_petNum; i++)
                {
                    string _petName = ES3.Load<string>("PetNm" + i.ToString()); //读取精灵的名称
    
                    int _petIndex = ES3.Load<int>("PetIndex" + i.ToString()); //读取精灵的下标
    
                    StaticData.AddPet(new PetSave(_petName,_petIndex));  //把读取到的精灵信息写入保存的类中
    
                }
    
    
            }
    
        }
    
    
    }
    
    

    StaticData

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    /// <summary>
    /// 静态类
    /// </summary>
    public static class StaticData {
    
        public static int BallNum = 50; //精灵球数量的全局变量 初始化为5;
    
        public static int FoodNum = 20; //食物数量的全局变量 初始化为10;
    
        public static int CatchingPetIndex; //当前主要捕捉的小精灵在预制体集合中的序列号
        
        public static List<PetSave> PetList=new List<PetSave>(); //申请列表储存的捕捉小精灵类
    
        /// <summary>
        /// 捕捉小精灵的添加到集中去  向全局数据中小精灵列表添加小精灵
        /// </summary>
        /// <param name="petsave">储存小精灵的属性类</param>
        public static void AddPet(PetSave petSave) {
    
            PetList.Add(petSave);
        }
    
        /// <summary>
        /// 通过小精灵在预制体集合中的序号来获取它的精灵类型
        /// </summary>
        /// <param name="index">小精灵在集合中的序号</param>
        /// <returns>返回的类型</returns>
        public static string GetType(int index) {
    
            if (index == 0)
            {
                return "小熊";
            }
            else if (index == 1)
            {
                return "小牛";
            }
            else if (index == 2)
            {
                return "兔子";
            }
            else if (index == 3)
            {
                return "小鸡";
            }
            else if (index == 4)
            {
                return "老虎";
            }
            else if (index == 5)
            {
                return "猴子";
            }
            else if (index == 6)
            {
                return "白猫";
            }
            else if (index == 7)
            {
                return "狮子";
            }
            else if (index == 8)
            {
                return "企鹅";
            }
            else if (index == 9)
            {
                return "犀牛";
            }
            else
            {
                return "小黄狗";
            }
    
    
            //switch (index)
            //{
            //    case 0:
            //        return "小熊";
    
            //    case 1:
            //        return "小牛";
    
            //    case 2:
            //        return "兔子";
            //    case 3:
            //        return "小鸡";
            //    case 4:
            //        return "老虎";
            //    case 5:
            //        return "猴子";
            //    case 6:
            //        return "白猫";
            //    case 7:
            //        return "狮子";
            //    case 8:
            //        return "企鹅";
            //    case 9:
            //        return "犀牛";
    
            //    default:
            //        return "小黄狗";
            //}
    
        }
    
    }
    
    
    6、Store

    Store_Au

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Store_Au : MonoBehaviour {
    
        public static Store_Au Instance;    //单例模式
    
        private AudioSource AuS;    //声音组件持有的引用
    
    
         void Awake()
        {
            Instance = this; //单例模式    
        }
    
        void Start () {
    
            AuS = gameObject.transform.GetComponent<AudioSource>(); //声音组件的赋值
        }
        
    
        void Update () {
            
        }
    
        /// <summary>
        /// 点击按钮的返回声效事件
        /// </summary>
        public void BtnAuPlay() {
    
            AuS.Play(); //播放声效的事件
        }
    
    
    }
    
    
    

    StoreInsPet

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class StoreInsPet : MonoBehaviour {
    
        public Transform[] Pos;//储存宠物栏中小精灵的生成点
    
        private GameObject[] pets;//储存所有精灵的预制体
    
        private GameObject[] petShow = new GameObject[3]; //在仓库中显示出来的小精灵
    
        void Awake()
        {
            pets = Resources.LoadAll<GameObject>("Pets"); //加载所有的小精灵
        }
    
        void Start () {
    
            InsPet(); //调用此方法在仓库中的显示 
        }
        
    
        void Update () {
            
        }
    
        /// <summary>
        /// 仓库中生成小精灵的函数
        /// </summary>
        public void InsPet() {
    
            int _petNum = StaticData.PetList.Count;//通过全局变量储存好的精灵数量来判断 已经捕捉好的精灵数量
    
            //只有数量大于0 的情况下才执行如下方法
            if (_petNum>0)
            {
                for (int i = 0; i < petShow.Length; i++)
                {
    
                    if (_petNum-1<i) //如果数量减1小于i  排列的顺序不变  返回
                    {
                        return;
                    }
    
    
                    PetSave _petInfo = StaticData.PetList[i]; //从全局类中 获取对应的序列号中的小精灵属性   petsave类中储存的是  名字和序列号
    
                    Instantiate(pets[_petInfo.PetIndex],Pos[i].position,Pos[i].rotation); //实例化小精灵  游戏对象就是 全局变量中对应的序列号的预制体   位置是生成的仓库位置点
    
                    string _petNm=_petInfo.PetName;   //获取对应中精灵的名字  以致调用刷新名字的方法
    
                    StoreUIMgr.Instance.UpDatePetNm(i,_petNm);//刷新精灵的名字
    
                    string _petType = StaticData.GetType(_petInfo.PetIndex); //获取精灵的种类
    
                    StoreUIMgr.Instance.UpDatePettype(i,_petType);  //刷新精灵的类型
    
                }
    
            }
    
    
    
        }
    }
    
    

    StoreUIMgr

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using UnityEngine.UI;
    
    public class StoreUIMgr : MonoBehaviour {
    
    
        public Text[] Tx_PetNm; //储存精灵名字的数组
    
        public Text[] Tx_PetType; //储存精灵类型的数组
    
    
        public static StoreUIMgr Instance; //单例模式
    
         void Awake()
        {
            Instance = this; //单例模式赋值  
        }
    
        void Start () {
            
    
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 刷新小精灵的名字
        /// </summary>
        /// <param name="index">小精灵在数组中的序号</param>
        /// <param name="strNm">小精灵要显示的名字</param>
        public void UpDatePetNm(int index,string strNm) {
            Tx_PetNm[index].text = strNm;
        }
    
    
    
      /// <summary>
      /// 刷新小精灵的类型
      /// </summary>
      /// <param name="index">在数组中小精灵的序号</param>
      /// <param name="strType">显示小精灵的类型</param>
        public void UpDatePettype(int index,string strType) {
    
            Tx_PetType[index].text = strType;
        }
    
    
    
        /// <summary>
        /// 跳转到场景中的按钮
        /// </summary>
        public void Btn_ToMap() {
    
            Store_Au.Instance.BtnAuPlay(); //播放点击按钮的声效
            SceneManager.LoadScene("PKGOMain"); //跳转到主场景
        }
    
        /// <summary>
        /// 仓库中保存按钮
        /// </summary>
        public void Btn_Save() {
    
            SaveAndLoad.Save(); //保存数据的方法
        }
    
    }
    
    

    三、效果展示

    相关文章

      网友评论

          本文标题:AR开发实战Vuforia项目之PokemonGo(二、基于Lb

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