筆記29 導航系統項目聯繫:塔防遊戲

場景(起始點、終點)、敵人+代碼

在這裏插入圖片描述

代碼:終點EndControl

//如果進入觸發區域
    private void OnTriggerEnter(Collider other)
    {
        //如果是敵人
        if(other.tag == "Enemy")
        {
            //TODO:減血
             UIControl.Instance.AddHp(-1);
            //銷燬敵人
            Destroy(other.gameObject);
        }
    }

代碼:敵人EnemyControl

using UnityEngine.AI;

public class EnemyControl : MonoBehaviour
{
     // 血量
    public int Hp = 100;
    //死亡後,獎勵10元。
    public int Money = 10;
    //拿到導航組件,因爲這個組件是在AI名稱空間裏的,所以需要添加using UnityEngine.AI;
    private NavMeshAgent agent;
    //拿到終點的位置。因爲導航最終是導向那裏
    private Transform End;

    void Start()
    {
        //在這裏得到
        //由於這裏物體比較少,所以直接尋找
        End = GameObject.Find("End").transform;
        //獲取導航
        agent = GetComponent<NavMeshAgent>();
        //導航到終點的位置
        agent.SetDestination(End.position);

    }

    //受到攻擊。attack是傷害值,後期會傳進來。
    public void GetHit(int attack)
    {
        //掉血。
        Hp -= attack;
        if(Hp<= 0)
        {
            //錢數增加10元
            UIControl.Instance.AddMoney(Money);
            //銷燬自己
            Destroy(gameObject);
        }
    }

起始點+代碼StartControl

在這裏插入圖片描述

//拿到怪物的預設體,因爲怪物不止一種,所以用數組
    public GameObject[] Enemy;
    //出怪的間隔時間
    public float EnemySpawnCD = 1f;
    //一波怪的數量
    public int EnemyCount = 10;
    //每波怪之間的間隔時間
    public float EnemyTimer = 5f;

    //以下這些不用開放給外界
    //當前怪的個數
    private int count = 0;
    //當前的第幾波怪
    private int index = 0;
    //計時器
    private float timer = 0;

    void Start()
    {
        //起初當前怪的數量等於一波怪的數量
        count = EnemyCount;
    }

    void Update()
    {
        //如果當前怪物波數超出索引,退出
        if(index >= Enemy.Length)
        {
            return;
        }
        //計時器計時
        timer += Time.deltaTime;
        //如果計時器到時,產生怪物
        if(timer > EnemySpawnCD)
        {
            if(count > 0)
            {
                //產生當前的怪物。實例化(索引,位置,旋轉)
                Instantiate(Enemy[index], transform.position, transform.rotation);
                //待實例化的怪的數量在實例化後,減少
                count--;
                //計時器重置
                timer = 0;
            }
            else
            {
                //該下一波怪了
                //首先數量恢復
                count = EnemyCount;
                //波數增加
                index++;
                //EnemyTimer每波怪之間的間隔時間,默認是5秒。
                //此處計時器直接等於 -5,那就直接再去計時timer += Time.deltaTime;
                timer = -EnemyTimer;
            }
        }
    }

代碼:子彈BulletControl

創建子彈,添加腳本。子彈設置爲觸發,關聯子彈的“目標敵人”。

    // 目標敵人(會盯住敵人攻擊)
    public EnemyControl TargetEnemy;
    //威力。
    public int Attack = 40;
    //速度
    public float Speed = 5f;

    void Start()
    {        
    }

    void Update()
    {
        //像這種有目標的( 此處,有目標敵人),上來要做“非空判斷”。
        if(TargetEnemy == null)
        {
            //銷燬。就是說,比如左右兩發子彈同時都攻擊一個目標,當第一顆子彈已經把目標炸燬了,那麼第二顆,就自己銷燬。
            Destroy(gameObject);
            return;
        }
        
        //朝向敵人的向量:目標點的位置-我的位置
        Vector3 dir = TargetEnemy.transform.position - transform.position;
        //朝目標走過去(方向*速度*單位轉換成每秒)
        transform.Translate(dir * Speed * Time.deltaTime);

        //擊中敵人。(判斷子彈和目標的距離,如果小於0.5米,就算擊中敵人了)
        if (Vector3.Distance(TargetEnemy.transform.position, transform.position) < 0.5f)
        {
            //調用敵人腳本里受到傷害的方法。把傷害值40傳回去
            TargetEnemy.GetHit(Attack);
            //銷燬
            Destroy(gameObject);
        }
    }

防禦塔+代碼BatteryControl

在這裏插入圖片描述

//子彈預設體
    public GameObject BulletPre;
    //攻擊間隔,此處,半秒打一發子彈
    public float FireCD = 0.5f;
    //攻擊力
    public int Attack = 40;
    //價格。默認50元
    public static int Money = 50;

    //計時器
    private float timer = 0;
    //原理:每個炮臺將能打到的敵人保存在一個列表,然後就盯着第一個敵人目標打。
    //攻擊列表。因爲能打到的目標敵人是在會變化的,所以使用動態列表List
    private List<EnemyControl> Enemys;

    void Start()
    {
        //實例化
        Enemys = new List<EnemyControl>();
    }

    void Update()
    {
        //計時器
        timer += Time.deltaTime;
        //遍歷,如果有敵人死亡了,就將其從攻擊列表中移除
        for (int i = 0; i<Enemys.Count; i++)
        {
            EnemyControl enemy = Enemys[i];
            if (enemy == null)
            {
                Enemys.Remove(enemy);
            }
        }
        //如果敵人屬於攻擊列表,並且到達攻擊間隔
        if (Enemys.Count > 0 && timer>FireCD)
        {
            //攻擊
            //需要實例化子彈,並得到子彈的腳本。返回值(子彈的腳本) = 實例化(什麼東西,位置,旋轉).得到子彈的腳本
            BulletControl bc = Instantiate(BulletPre, transform.position + Vector3.up, Quaternion.identity).GetComponent<BulletControl>();
            //給子彈設定攻擊目標:數組裏的第一個
            bc.TargetEnemy = Enemys[0];
            //攻擊力。子彈的攻擊力等於防禦塔的攻擊力。此處,子彈的默認攻擊力就無效了。
            bc.Attack = Attack;
                        
            //重置時間(如果沒有重置時間,只會發射一顆子彈)
            timer = 0;
        }
    }

    //如果有敵人進入到攻擊區域
    private void OnTriggerEnter(Collider other)
    {
        if(other.tag == "Enemy")
        {
            //往列表裏添加敵人,得到它身上EnemyControl這個腳本
            Enemys.Add(other.GetComponent<EnemyControl>());
        }
    }
    //如果有敵人離開攻擊區域
    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "Enemy")
        {
            //移除
            Enemys.Remove(other.GetComponent<EnemyControl>());
        }
    }

臺階+代碼CubeControl

在這裏插入圖片描述

//防禦塔(炮臺)預設體
    public GameObject BatteryPre;

    void Start()
    {
        
    }

    //鼠標進入
    private void OnMouseEnter()
    {
        //給Cube改顏色。拿到渲染組件.修改它裏面材質.顏色 = 新顏色
        GetComponent<MeshRenderer>().material.color = Color.green;

    }
    //鼠標離開
    private void OnMouseExit()
    {
        //改回原色。即新顏色爲白色
        GetComponent<MeshRenderer>().material.color = Color.white;
    }
    //注意:鼠標操作,第一種用回調;第二種用射線(鼠標點的位置,想屏幕裏打一條射線,打在哪個Cube上,就在哪個上創建。
    //第一種:當鼠標在它上面按下的時候
    private void OnMouseDown()
    {
        //如果我身上的子節點爲零,說明身上沒有防禦塔。
        //並且,能夠花費購買該防禦塔所需的費用。如果能花,返回值爲true;否則爲false。
        if (transform.childCount == 0 && UIControl.Instance.GetMoney(BatteryControl.Money))
        {
            //實例化(創建防禦塔)。+ Vector3.up是將其位置向上提了一點
            Instantiate(BatteryPre, transform.position + Vector3.up, Quaternion.identity);
        }
    }

金錢、生命值+代碼UIControl

在這裏插入圖片描述

   //寫成單例
    public static UIControl Instance;
    //錢數。添加名稱空間using UnityEngine.UI;
    public Text MoneyText;
    //生命值???
    public Text HpText;
    //金錢,默認60
    private int money = 60;
    //生命值
    private int Hp = 10;

    void Awake()
    {
        //單例……
        Instance = this;
    }

    // 添加金錢(消滅敵人得金錢,敵人代碼)
    public void AddMoney(int money)
    {
        this.money += money;
        //刷新文本
        MoneyText.text = this.money + "";
    }
    //消耗金錢。返回的不是void,而是布爾值。(添加防禦塔,消耗金錢。防禦塔代碼)
    public bool GetMoney(int money)
    {
        //如果擁有的錢大於等於防禦塔的價格
        if (this.money >= money)
        {
            this.money -= money;
            //刷新文本
            MoneyText.text = this.money + "";
            //返回true
            return true;
        }
        //否則就返回false,說明消耗失敗了
        return false;
    }
    //添加生命值
    public void AddHp(int hp)
    {
        Hp += hp;
        //刷新文本
        HpText.text = this.Hp + "";
    }

完善



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章