AR开发实战Vuforia项目之守护森林消灭伐木工(塔防游戏)

一、主要框架

AR开发实战Vuforia项目之守护森林消灭伐木工(塔防游戏)_第1张图片

二、模型

AR开发实战Vuforia项目之守护森林消灭伐木工(塔防游戏)_第2张图片

三、关键代码

Bullet

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour {

    //防御塔的引用
    public GameObject tower;

    //所有敌人的引用;
    private EnemyController[] enemys;

    //开始发射子弹的距离;
    private float distance;

    //最近的敌人;
    private EnemyController nearestEnemy;

    //判断塔与敌人的距离;
    private float dis;


    //子弹伤害值;静态的一般公开的才方便调用
    public  static float bulletDamage;

    void Start () {


        //定义伤害值
        bulletDamage = 10f;
    }
    

    void Update () {
        //寻找敌人的方法
        //--------------------------------------------------------------

        //设置最近距离;
        distance = 500f;
        //获取所有子物体;
        enemys = FindObjectsOfType();
        //遍历所有子物体 以获取最近敌人;
        for (int i = 0; i < enemys.Length; i++)
        {
            //获取两物体间的距离
            dis = Vector3.Distance(tower.transform.position, enemys[i].transform.position);
            //判断是否是防御距离二发射子弹;
            if (dis < distance)
            {
                distance = dis;
                nearestEnemy = enemys[i];
                Debug.Log("最近敌人");
            }

        }
        //--------------------------------------------------------------

        //判断如果最近敌人不为空 就发射子弹;
        if (nearestEnemy!=null)
        {
           
            //子弹的位置 从塔的位置移向到敌人的位置;
            this.transform.position = Vector3.MoveTowards(this.transform.position,nearestEnemy.transform.position,10f); //参数3:移动速度;
           //塔的方向 朝向 最近敌人的位置;
           tower.transform.LookAt(nearestEnemy.transform);
            if (this.transform.position==nearestEnemy.transform.position)
            {
                //判断子弹到达最近敌人时候 销毁子弹
                Destroy(this.gameObject);
                Debug.Log("子弹销毁");
                //释放资源
                Resources.UnloadUnusedAssets();
            }
            else
            {
                Destroy(this.gameObject,1f);
            }
        }

        //如果敌人为空 那就把子弹销毁掉,不要停在半空中;
        if (nearestEnemy==null)
        {
            Destroy(this.gameObject);
            //释放资源
            Resources.UnloadUnusedAssets();
        }
    }
}

EnemyAnimation

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// 
/// 控制敌人动画
/// 
public class EnemyAnimation : MonoBehaviour {

    //获取 动画 组件
    private Animator anim;

    //获取EnemyController的工具状态 避免实例化就开始攻击;
    EnemyController enemyController;


    //播放音效
    private AudioSource mAudioSource;

    void Start () {
        //获取敌人身上的动画组件
        anim = this.GetComponent();

        //获取脚本组件;
        enemyController = this.GetComponent();

        //获取音效的音频;
        mAudioSource = this.GetComponent();
    }
    

    void Update () {

        //判断塔销毁的状态
        if (TowerController.isDamage==false)
        {
            //获取EnemyControoler脚本上的布尔值 是否可以攻击
            if (enemyController.isAttack == true)
            {
                //设置动画状态的布尔值
                anim.SetBool("Attack", true); //参数1:动画条件 参数文2:动画值             
                anim.SetBool("Walk", true);
                anim.SetBool("Idle", false);

            
            }
           
        }
        else if (TowerController.isDamage == true)
        {          
                //设置动画状态的布尔值
                anim.SetBool("Attack", false); //参数1:动画条件 参数文2:动画值
                anim.SetBool("Walk", false);
                anim.SetBool("Idle",true);
          
        }

    }

    /// 
    /// 播放砍塔的声音 只需在动画中插入这个事件就好,不要加括号
    /// 
    public void KanTa() {
        //播放砍塔音效;
        mAudioSource.Play();
    }

}

EnemyController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// 
/// 敌人控制脚本
/// 
public class EnemyController : MonoBehaviour {

    //防御塔的引用
    public GameObject towerPrefab;

    //敌人移动速度;
    private float speed=2f;
    //用来判断敌人与塔的距离;
    private  float distance;

    //设置布尔值;必须是公开的,方便调用
    public  bool isAttack;

    //设置敌人的攻击力度 设置静态方便调用 不用实例化出来
    public static float damage=10f;

    //设置敌人的生命值;
    public  float enemyLife = 80f;


    //获取画布的组件以及敌人血条image;
   private  Canvas canvas;
   private  Image blood;

 

    void Start () {

        //刚开始时 不攻击
        isAttack = false;

        //获取画布的组件;
        canvas = this.GetComponentInChildren();
        //获取血条显示图片;
        blood = canvas.GetComponentInChildren();

    
    }
    
    
    void Update () {

        //只有塔还没被摧毁的时候才执行这个移动
        if (TowerController.isDamage==false)
        {
            //移动到防御塔
            //  this.transform.position = Vector3.MoveTowards(this.transform.position,towerPrefab.transform.position,2f); //参数1:当前位置 参数2:目标位置 参数3:移动时间
            this.transform.position = Vector3.MoveTowards(this.transform.position, towerPrefab.transform.position, speed);
            //测试
            //if (this.transform.position==towerPrefab.transform.position)
            //{
            //    Debug.Log("兵临城下");
            //} 

            //返回2点之间的距离;
            distance = Vector3.Distance(this.transform.position, towerPrefab.transform.position);
            //判断距离停止移动 并且播放攻击的动画;设置攻击为真
            if (distance <= 120f)
            {
                speed = 0;
                isAttack = true;
              
            }
        }
    }

    /// 
    ///子弹与敌人碰撞
    /// 
    /// 
    private void OnTriggerEnter(Collider collider)
    {
        if (collider.gameObject.tag=="bullet")
        {
            Debug.Log("敌人被攻击了");
            //敌人受伤害
            enemyLife -= Bullet.bulletDamage;
            //测试敌人生命值;
            Debug.Log("敌人生命值:"+enemyLife);

            //显示血条的图片;
            blood.fillAmount = enemyLife / 80;
            if (enemyLife<=0)
            {
                Destroy(this.gameObject);
                Debug.Log("敌人消灭了!");
              //  enemyLife = 80;
            }

        }
    }


}


MyTrackableEventHandler

using UnityEngine;

namespace Vuforia
{
    /// 
    /// A custom handler that implements the ITrackableEventHandler interface.
    /// 
    public class MyTrackableEventHandler : MonoBehaviour,
                                                ITrackableEventHandler
    {
        //防御塔预制体的引用
        public GameObject towerPrefab;

        //敌人的预制体的引用 数组 随机生成
        public GameObject[] enemyPrefab;

        //敌人的位置
        // public Transform enemyPoint1;
        public Transform[] enemyPoint;


        //定时器 每隔2秒钟就生成一个敌人
        public float timeGo = 3f;
        //用来接收输入时间的
        private  float startTime ;
        //避免update中的方法不断识别 定义一个标志位
        bool isFoundEnemy;
        #region PRIVATE_MEMBER_VARIABLES

        private TrackableBehaviour mTrackableBehaviour;
    
        #endregion // PRIVATE_MEMBER_VARIABLES



        #region UNTIY_MONOBEHAVIOUR_METHODS
    
        void Start()
        {
            //给时间赋值
            startTime = timeGo;

            //刚开始不可识别;
            isFoundEnemy = false;

            mTrackableBehaviour = GetComponent();
            if (mTrackableBehaviour)
            {
                mTrackableBehaviour.RegisterTrackableEventHandler(this);
            }
        }

        #endregion // UNTIY_MONOBEHAVIOUR_METHODS



        #region PUBLIC_METHODS

        /// 
        /// Implementation of the ITrackableEventHandler function called when the
        /// tracking state changes.
        /// 
        public void OnTrackableStateChanged(
                                        TrackableBehaviour.Status previousStatus,
                                        TrackableBehaviour.Status newStatus)
        {
            if (newStatus == TrackableBehaviour.Status.DETECTED ||
                newStatus == TrackableBehaviour.Status.TRACKED ||
                newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
            {
                //事件中识别防御塔的方法;
                OnTrackingFound();
                //重新识别之后塔没有被破坏
                TowerController.isDamage = false;
                //事件中是识别敌人的方法;
                OnTrackingEnemyFound();
            }
            else
            {
                OnTrackingLost();
            }
        }

        #endregion // PUBLIC_METHODS

        //不断识别敌人
         void Update()
        {

            //判断塔的状态 只有不被销毁的时候才实例化敌人
            if (TowerController.isDamage==false)
            {
                //时间递减
                timeGo -= Time.deltaTime;
                //如果时间归零并且满足条件为真
                if (timeGo <= 0 && isFoundEnemy == true)
                {
                    OnTrackingEnemyFound();
                    //时间回到初始化值
                    timeGo = startTime;
                }

            }


        }



        #region PRIVATE_METHODS


        private void OnTrackingFound()
        {

            //识别防御塔时候实例化
            GameObject Tower = GameObject.Instantiate(towerPrefab) as GameObject;
            //设置父类
            Tower.transform.parent = this.transform;
            //设置位置
            Tower.transform.position = this.transform.position;


            ////识别敌人
            //GameObject Enemy = GameObject.Instantiate(enemyPrefab[Random.Range(0,3)]) as GameObject;
            //Enemy.transform.parent = this.transform;
            //// Enemy.transform.position = this.transform.position+new Vector3(3,0,3);  //加个位置
            ////敌人的位置
            //Enemy.transform.position = enemyPoint[Random.Range(0, 3)].position;

            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
        }

        /// 
        /// 识别敌人的方法
        /// 
        private void OnTrackingEnemyFound() {

            //找到了设置为真
            isFoundEnemy = true;
            //识别敌人
            GameObject Enemy = GameObject.Instantiate(enemyPrefab[(int)Random.Range(0, 3)]) as GameObject;
            Enemy.transform.parent = this.transform;
            // Enemy.transform.position = this.transform.position+new Vector3(3,0,3);  //加个位置
            //敌人的位置
            // Enemy.transform.position = enemyPoint1.position;
            //位置信息随机
            int random = (int)Random.Range(0, 3);
            Enemy.transform.position = enemyPoint[random].position;
            //敌人的朝向 第一种方法
            //if (random == 0)
            //{
            //    Enemy.transform.rotation = Quaternion.AngleAxis(120, Vector3.up);
            //}
            //if (random==1)
            //{
            //    Enemy.transform.rotation = Quaternion.AngleAxis(240,Vector3.up);
            //}
            //if (random==2)
            //{
            //    Enemy.transform.rotation = Quaternion.AngleAxis(320,Vector3.up);
            //}
            //敌人的朝向 第二种方法
            Enemy.transform.LookAt(towerPrefab.transform);

        }

        private void OnTrackingLost()
        {
            //没找到 设置为false
            isFoundEnemy = false;
            //防御塔没找到的时候
            TowerController tower = GetComponentInChildren();
            //判断一下没找的时候销毁
            if (tower!=null)
            {
                //销毁
                DestroyImmediate(tower.gameObject);
                //释放资源
                Resources.UnloadUnusedAssets();
            }


            //同样 识别丢失的时候敌人销毁
            //EnemyController enemy = GetComponentInChildren();
            EnemyController[] enemy = GetComponentsInChildren();
            if (enemy!=null)
            {
                //for  循环 逐个销毁、第一种方法
                //for (int i = 0; i < enemy.Length; i++)
                //{
                //    EnemyController E = enemy[i];
                //    Destroy(E.gameObject);
                //}

                foreach (EnemyController E in enemy)
                {
                    DestroyImmediate(E.gameObject);
                    Resources.UnloadUnusedAssets();
                }

                //DestroyImmediate(enemy.gameObject);
                //Resources.UnloadUnusedAssets();
            }

            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
        }

        #endregion // PRIVATE_METHODS
    }
}

TowerController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TowerController : MonoBehaviour {


    //设置塔的生命值
    private float towerLife = 100f;

    //判断塔是否销毁(生命值为零时) 公开的 方便敌人停止攻击动画的控制
    public static bool isDamage=false;


    //获取画布的引用
    private Canvas canvas;

    //获取画布下的image;
    private Image blood;


    //子弹的预制体
    public GameObject bulletPrefab;

    //子弹生成时间 计时器
    //  private float timeGo = 0;

    //播放音效
    private AudioSource mAudioSource;

    void Start () {

        //给画布和血条赋值;
        canvas = GetComponentInChildren();
        blood = canvas.GetComponentInChildren();

        //获取子弹发射的音频;
        mAudioSource = this.GetComponent();

    }

    void Update () {
        //发射子弹的时间
        //timeGo += Time.deltaTime;
        //if (timeGo>0.3f)
        //{
        //    //执行子弹生成的方法;
        //    CreateBullet();
        //    timeGo = 0f;
        //}
        //以上代码是测试时用
        //--------------------------
        //点击屏幕时调用
        if (Input.GetMouseButtonDown(0))
        {
            CreateBullet();

            //播放子弹发射音效;
            mAudioSource.Play();
        }
    }

     void OnTriggerEnter(Collider collider)
    {
        if (collider.gameObject.tag== "weapon")
        {
            towerLife -= EnemyController.damage; //调用敌人的破坏力
            //测试塔的防御值
            Debug.Log(towerLife);

            //显示血条 画布下的属性
            blood.fillAmount = towerLife / 100;

            //判断生命力小于零的时候 销毁塔和设置为真
            if (towerLife<=0)
            {
                Destroy(this.gameObject);
                isDamage = true;
            }
        }
    }

    /// 
    /// 实例化子弹的方法
    /// 
    void CreateBullet() {

        //实例化子弹
        GameObject bullet = GameObject.Instantiate(bulletPrefab) as GameObject;
        //设置父类关系
        bullet.transform.parent = this.transform;
        //设置位置
        bullet.transform.position = this.transform.position+new Vector3(0,200,0);
        //设置子弹的随机颜色
        bullet.GetComponent().material.color = new Color(Random.Range(0f,1f),Random.Range(0f,1f),Random.Range(0f,1f));

        Debug.Log("1111111111111");

    }



}

四、展示效果

你可能感兴趣的:(AR开发实战Vuforia项目之守护森林消灭伐木工(塔防游戏))