AR開發(fā)實戰(zhàn)Vuforia項目之守護森林消滅伐木工(塔防游戲)

一政己、主要框架

二、模型

三晨炕、關(guān)鍵代碼

Bullet

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

public class Bullet : MonoBehaviour {

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

    //所有敵人的引用衫画;
    private EnemyController[] enemys;

    //開始發(fā)射子彈的距離;
    private float distance;

    //最近的敵人瓮栗;
    private EnemyController nearestEnemy;

    //判斷塔與敵人的距離削罩;
    private float dis;


    //子彈傷害值;靜態(tài)的一般公開的才方便調(diào)用
    public  static float bulletDamage;

    void Start () {


        //定義傷害值
        bulletDamage = 10f;
    }
    

    void Update () {
        //尋找敵人的方法
        //--------------------------------------------------------------

        //設(shè)置最近距離费奸;
        distance = 500f;
        //獲取所有子物體弥激;
        enemys = FindObjectsOfType<EnemyController>();
        //遍歷所有子物體 以獲取最近敵人;
        for (int i = 0; i < enemys.Length; i++)
        {
            //獲取兩物體間的距離
            dis = Vector3.Distance(tower.transform.position, enemys[i].transform.position);
            //判斷是否是防御距離二發(fā)射子彈愿阐;
            if (dis < distance)
            {
                distance = dis;
                nearestEnemy = enemys[i];
                Debug.Log("最近敵人");
            }

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

        //判斷如果最近敵人不為空 就發(fā)射子彈微服;
        if (nearestEnemy!=null)
        {
           
            //子彈的位置 從塔的位置移向到敵人的位置;
            this.transform.position = Vector3.MoveTowards(this.transform.position,nearestEnemy.transform.position,10f); //參數(shù)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;

/// <summary>
/// 控制敵人動畫
/// </summary>
public class EnemyAnimation : MonoBehaviour {

    //獲取 動畫 組件
    private Animator anim;

    //獲取EnemyController的工具狀態(tài) 避免實例化就開始攻擊舒裤;
    EnemyController enemyController;


    //播放音效
    private AudioSource mAudioSource;

    void Start () {
        //獲取敵人身上的動畫組件
        anim = this.GetComponent<Animator>();

        //獲取腳本組件;
        enemyController = this.GetComponent<EnemyController>();

        //獲取音效的音頻觉吭;
        mAudioSource = this.GetComponent<AudioSource>();
    }
    

    void Update () {

        //判斷塔銷毀的狀態(tài)
        if (TowerController.isDamage==false)
        {
            //獲取EnemyControoler腳本上的布爾值 是否可以攻擊
            if (enemyController.isAttack == true)
            {
                //設(shè)置動畫狀態(tài)的布爾值
                anim.SetBool("Attack", true); //參數(shù)1:動畫條件 參數(shù)文2:動畫值             
                anim.SetBool("Walk", true);
                anim.SetBool("Idle", false);

            
            }
           
        }
        else if (TowerController.isDamage == true)
        {          
                //設(shè)置動畫狀態(tài)的布爾值
                anim.SetBool("Attack", false); //參數(shù)1:動畫條件 參數(shù)文2:動畫值
                anim.SetBool("Walk", false);
                anim.SetBool("Idle",true);
          
        }

    }

    /// <summary>
    /// 播放砍塔的聲音 只需在動畫中插入這個事件就好腾供,不要加括號
    /// </summary>
    public void KanTa() {
        //播放砍塔音效;
        mAudioSource.Play();
    }

}

EnemyController

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

/// <summary>
/// 敵人控制腳本
/// </summary>
public class EnemyController : MonoBehaviour {

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

    //敵人移動速度鲜滩;
    private float speed=2f;
    //用來判斷敵人與塔的距離伴鳖;
    private  float distance;

    //設(shè)置布爾值;必須是公開的徙硅,方便調(diào)用
    public  bool isAttack;

    //設(shè)置敵人的攻擊力度 設(shè)置靜態(tài)方便調(diào)用 不用實例化出來
    public static float damage=10f;

    //設(shè)置敵人的生命值榜聂;
    public  float enemyLife = 80f;


    //獲取畫布的組件以及敵人血條image;
   private  Canvas canvas;
   private  Image blood;

 

    void Start () {

        //剛開始時 不攻擊
        isAttack = false;

        //獲取畫布的組件嗓蘑;
        canvas = this.GetComponentInChildren<Canvas>();
        //獲取血條顯示圖片须肆;
        blood = canvas.GetComponentInChildren<Image>();

    
    }
    
    
    void Update () {

        //只有塔還沒被摧毀的時候才執(zhí)行這個移動
        if (TowerController.isDamage==false)
        {
            //移動到防御塔
            //  this.transform.position = Vector3.MoveTowards(this.transform.position,towerPrefab.transform.position,2f); //參數(shù)1:當(dāng)前位置 參數(shù)2:目標(biāo)位置 參數(shù)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);
            //判斷距離停止移動 并且播放攻擊的動畫桩皿;設(shè)置攻擊為真
            if (distance <= 120f)
            {
                speed = 0;
                isAttack = true;
              
            }
        }
    }

    /// <summary>
    ///子彈與敵人碰撞
    /// </summary>
    /// <param name="other"></param>
    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
{
    /// <summary>
    /// A custom handler that implements the ITrackableEventHandler interface.
    /// </summary>
    public class MyTrackableEventHandler : MonoBehaviour,
                                                ITrackableEventHandler
    {
        //防御塔預(yù)制體的引用
        public GameObject towerPrefab;

        //敵人的預(yù)制體的引用 數(shù)組 隨機生成
        public GameObject[] enemyPrefab;

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


        //定時器 每隔2秒鐘就生成一個敵人
        public float timeGo = 3f;
        //用來接收輸入時間的
        private  float startTime ;
        //避免update中的方法不斷識別 定義一個標(biāo)志位
        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<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();
                //重新識別之后塔沒有被破壞
                TowerController.isDamage = false;
                //事件中是識別敵人的方法;
                OnTrackingEnemyFound();
            }
            else
            {
                OnTrackingLost();
            }
        }

        #endregion // PUBLIC_METHODS

        //不斷識別敵人
         void Update()
        {

            //判斷塔的狀態(tài) 只有不被銷毀的時候才實例化敵人
            if (TowerController.isDamage==false)
            {
                //時間遞減
                timeGo -= Time.deltaTime;
                //如果時間歸零并且滿足條件為真
                if (timeGo <= 0 && isFoundEnemy == true)
                {
                    OnTrackingEnemyFound();
                    //時間回到初始化值
                    timeGo = startTime;
                }

            }


        }



        #region PRIVATE_METHODS


        private void OnTrackingFound()
        {

            //識別防御塔時候?qū)嵗?            GameObject Tower = GameObject.Instantiate(towerPrefab) as GameObject;
            //設(shè)置父類
            Tower.transform.parent = this.transform;
            //設(shè)置位置
            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");
        }

        /// <summary>
        /// 識別敵人的方法
        /// </summary>
        private void OnTrackingEnemyFound() {

            //找到了設(shè)置為真
            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()
        {
            //沒找到 設(shè)置為false
            isFoundEnemy = false;
            //防御塔沒找到的時候
            TowerController tower = GetComponentInChildren<TowerController>();
            //判斷一下沒找的時候銷毀
            if (tower!=null)
            {
                //銷毀
                DestroyImmediate(tower.gameObject);
                //釋放資源
                Resources.UnloadUnusedAssets();
            }


            //同樣 識別丟失的時候敵人銷毀
            //EnemyController enemy = GetComponentInChildren<EnemyController>();
            EnemyController[] enemy = GetComponentsInChildren<EnemyController>();
            if (enemy!=null)
            {
                //for  循環(huán) 逐個銷毀逻澳、第一種方法
                //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 {


    //設(shè)置塔的生命值
    private float towerLife = 100f;

    //判斷塔是否銷毀(生命值為零時) 公開的 方便敵人停止攻擊動畫的控制
    public static bool isDamage=false;


    //獲取畫布的引用
    private Canvas canvas;

    //獲取畫布下的image闸天;
    private Image blood;


    //子彈的預(yù)制體
    public GameObject bulletPrefab;

    //子彈生成時間 計時器
    //  private float timeGo = 0;

    //播放音效
    private AudioSource mAudioSource;

    void Start () {

        //給畫布和血條賦值;
        canvas = GetComponentInChildren<Canvas>();
        blood = canvas.GetComponentInChildren<Image>();

        //獲取子彈發(fā)射的音頻斜做;
        mAudioSource = this.GetComponent<AudioSource>();

    }

    void Update () {
        //發(fā)射子彈的時間
        //timeGo += Time.deltaTime;
        //if (timeGo>0.3f)
        //{
        //    //執(zhí)行子彈生成的方法苞氮;
        //    CreateBullet();
        //    timeGo = 0f;
        //}
        //以上代碼是測試時用
        //--------------------------
        //點擊屏幕時調(diào)用
        if (Input.GetMouseButtonDown(0))
        {
            CreateBullet();

            //播放子彈發(fā)射音效;
            mAudioSource.Play();
        }
    }

     void OnTriggerEnter(Collider collider)
    {
        if (collider.gameObject.tag== "weapon")
        {
            towerLife -= EnemyController.damage; //調(diào)用敵人的破壞力
            //測試塔的防御值
            Debug.Log(towerLife);

            //顯示血條 畫布下的屬性
            blood.fillAmount = towerLife / 100;

            //判斷生命力小于零的時候 銷毀塔和設(shè)置為真
            if (towerLife<=0)
            {
                Destroy(this.gameObject);
                isDamage = true;
            }
        }
    }

    /// <summary>
    /// 實例化子彈的方法
    /// </summary>
    void CreateBullet() {

        //實例化子彈
        GameObject bullet = GameObject.Instantiate(bulletPrefab) as GameObject;
        //設(shè)置父類關(guān)系
        bullet.transform.parent = this.transform;
        //設(shè)置位置
        bullet.transform.position = this.transform.position+new Vector3(0,200,0);
        //設(shè)置子彈的隨機顏色
        bullet.GetComponent<MeshRenderer>().material.color = new Color(Random.Range(0f,1f),Random.Range(0f,1f),Random.Range(0f,1f));

        Debug.Log("1111111111111");

    }



}

四陨享、展示效果

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末葱淳,一起剝皮案震驚了整個濱河市钝腺,隨后出現(xiàn)的幾起案子抛姑,更是在濱河造成了極大的恐慌,老刑警劉巖艳狐,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件定硝,死亡現(xiàn)場離奇詭異,居然都是意外死亡毫目,警方通過查閱死者的電腦和手機蔬啡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來镀虐,“玉大人箱蟆,你說我怎么就攤上這事」伪悖” “怎么了空猜?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長恨旱。 經(jīng)常有香客問我辈毯,道長,這世上最難降的妖魔是什么搜贤? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任谆沃,我火速辦了婚禮,結(jié)果婚禮上仪芒,老公的妹妹穿的比我還像新娘唁影。我一直安慰自己,他們只是感情好掂名,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布夭咬。 她就那樣靜靜地躺著,像睡著了一般铆隘。 火紅的嫁衣襯著肌膚如雪卓舵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天膀钠,我揣著相機與錄音掏湾,去河邊找鬼裹虫。 笑死,一個胖子當(dāng)著我的面吹牛融击,可吹牛的內(nèi)容都是我干的筑公。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼尊浪,長吁一口氣:“原來是場噩夢啊……” “哼匣屡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拇涤,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤捣作,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鹅士,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體券躁,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年掉盅,在試婚紗的時候發(fā)現(xiàn)自己被綠了也拜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡趾痘,死狀恐怖慢哈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情永票,我是刑警寧澤卵贱,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站瓦侮,受9級特大地震影響艰赞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肚吏,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一方妖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧罚攀,春花似錦党觅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至炫掐,卻和暖如春魁莉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工旗唁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留畦浓,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓检疫,卻偏偏與公主長得像讶请,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子屎媳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容