小白贪狼做塔防(3)

现在我们来探讨怪物的相关事宜:
首先我们给怪物加一个EnemyContrl脚本,用来储存怪物的各种属性以及寻路,各种动画。


怪物身上的组件以及脚本设置

话不多说,贴上代码先:

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

public class EnemyContrl : MonoBehaviour

{
    /// <summary>
    /// 敌人的伤害值
    /// </summary>
    public float Destruction;
    /// <summary>
    /// 子弹的伤害
    /// </summary>
    private float Damage;
    /// <summary>
    /// 怪物血量
    /// </summary>
    public float Blood = 100f;
    private float b ;
    /// <summary>
    /// 怪物要到达的终点
    /// </summary>
    public GameObject Pos;
    /// <summary>
    /// 自动寻路组件
    /// </summary>
    private NavMeshAgent agt;
    /// <summary>
    /// 定义动画控制器
    /// </summary>
    private Animator Ani;
    /// <summary>
    /// 死亡后销毁时间
    /// </summary>
    private float DestryTime = 3f;
    /// <summary>
    /// 计时器
    /// </summary>
    private float Timer = 0;

    private Slider sd;
    void Awake()
    {
        sd = transform.GetChild(3).GetChild(0).GetComponent<Slider>();
        sd.value = sd.maxValue = 1;
        b = Blood;
    }
    void Start()
    {
        //获取自动寻路组件
        agt = this.GetComponent<NavMeshAgent>();
        //获取动画控制组件
        Ani = this.GetComponent<Animator>();
        //将终点位置传递进去
        agt.SetDestination(Pos.transform.position);
    }

    // Update is called once per framea
    void Update()
    {
        transform.GetChild(3).transform.forward = Camera.main.transform.forward;
        //监测生命值
        EnemyDead(Blood);
        //检测是否到达水晶
        Attack();
    }
    public void EnemyHurt(float Damage)
    {
        Blood -= Damage;
         
        sd.value = Blood /b;
        
    }
    public void EnemyDead(float Blood)
    {
        if (Blood <= 0)
        {
            this.gameObject.GetComponent<Collider>().enabled = false;
            Destroy(this.gameObject.GetComponent<Rigidbody>());
            //杀怪物获得金币
            GameData.Instance.money += 10;
            Ani.SetBool("Dead", true);
            Ani.SetBool("Attack", false);
            //agt.SetDestination(this.transform.position);
            this.gameObject.GetComponent<NavMeshAgent>().enabled = false;
            Timer += Time.deltaTime;
            if (Timer >= DestryTime) {
                Destroy(this.gameObject);
            }
        }
        else
        {

        }
    }

    public void Attack()
    {
        if (Vector3.Distance(this.transform.position, Pos.transform.position) <= 3.5)
        {
            Ani.SetBool("Attack", true);
        }
    }
}

有了这些还不够,我们还需要创建一个怪物生成点 (一个空物体即可)
挂载EnemyCreatePos脚本,这里尚未使用对象池技术,想要使用该技术的请到我之前发的文章里找找灵感。
链接:http://www.jianshu.com/p/18950e18ea75

再编写生成脚本时,我们要提前想好自己需要几种不同种类的怪物,这里的不同种类不是指外形的不同,而是比如,地面怪物,空中怪物,甚至物理怪物或魔法怪物,我暂时只分出地面怪物,空中怪物两大类。
代码如下:

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

public class EnemyCreatePos : MonoBehaviour
{
    //public float CreateSpeed = 2;
    /// <summary>
    /// 波数
    /// </summary>
    public int boshu = 10;
    /// <summary>
    /// 每波间隔
    /// </summary>
    public float bowait = 5;
    /// <summary>
    /// 每波怪数量
    /// </summary>
    public int bonum = 10;
    /// <summary>
    /// 每个怪间隔
    /// </summary>
    public float numwait = 2;
    /// <summary>
    /// 第几波
    /// </summary>
    private int boNO;
    /// <summary>
    /// 每波第几个
    /// </summary>
    private int numNO;

    private string str;
    //void Start () {
    //    StartCoroutine("CreateEnemy");
    //}
    //public GameObject enemyPrefabHyp;
    // Use this for initialization
    void Start()
    {
        StartCoroutine(Test02(boshu));
    }

    // Update is called once per frame
    void Update()
    {

    }
    //num:一共产生多少波怪
    IEnumerator Test02(int num)
    {
        boNO = 0;
        while (boNO < num)
        {
            //Camera.main.transform.GetComponent<WeatherController>().weather = boNO % 3;
            
            GameObject.Find("Weather").transform.GetComponent<WeatherController>().weather = boNO / 3;
            GameObject.Find("Weather").transform.GetComponent<WeatherController>().Change();
            boNO++;
            yield return StartCoroutine(Test01(bonum));
            Debug.Log("第" + boNO + "波怪产生结束");
            //每波怪产生的时间差
            yield return new WaitForSeconds(bowait);
            Debug.Log("注意第" + (boNO + 1) + "波怪即将产生");
        }
        Debug.Log("GameOver");
    }
    //number:每波怪的数量
    IEnumerator Test01(int number)
    {
        numNO = 0;
        while (numNO < number)
        {
            numNO++;
            //每个怪产生的时间差
            if (boNO > 5)
                yield return new WaitForSeconds(numwait / 2);
            else
                yield return new WaitForSeconds(numwait);
            string a = ChooseEnemy(boNO,numNO);
            //GameObject enemy = (GameObject)Resources.Load("Prefabs_Enemy/mon_goblinWizard");
            GameObject enemy = (GameObject)Resources.Load("Prefabs_Enemy/"+a);
            enemy.GetComponent<EnemyContrl>().Pos = GameObject.FindGameObjectWithTag("WayPos");
            //print(enemy.GetComponent<EnemyContrl>().Pos.name);
            GameObject o;
            //如果在飞行怪,则拔高5
            if (enemy.tag == "FlyEnemy")
            {
                o = Instantiate(enemy, transform.position + Vector3.up * 5, transform.rotation);
            }
            else
                o =  Instantiate(enemy,transform.position,transform.rotation);
            o.transform.parent = transform;

        }

    }
    /// <summary>
    /// 选择怪物种类
    /// </summary>
    /// <param name="boNO"></param>波次
    /// <param name="numNO"></param>怪次
    /// <returns></returns>
    string ChooseEnemy(int boNO, int numNO)
    {

        switch(boNO % 3)
        {

            case 1:
                {
                    if (numNO < 8)
                    {
                        str = "AmurTiger_01";
                    }
                    else if (numNO < 10 && numNO >= 8)
                    {
                        str = "AmurTiger_02";
                    }
                    else
                    {
                        str = "AmurTiger_03";
                    }
                    break;
                }
            case 2:
                {
                    if (numNO < 8)
                    {
                        str = "GiantBat";
                    }
                    else if (numNO < 10 && numNO >= 8)
                    {
                        str = "GiantBat_2";
                    }
                    else
                    {
                        str = "GiantBat_3";
                    }
                    break;
                }
            case 3:
                {
                    if (numNO < 8)
                    {
                        print("3-1");
                        str = "Manticore_01";
                    }
                    else if (numNO < 10 && numNO >= 8)
                    {
                        print("3-2");
                        str = "Manticore_02";
                    }
                    else
                    {
                        str = "Manticore_03";
                    }
                    break;
                }
            case 0:
                {
                    if (numNO < 4)
                    {
                        str = "GiantBat_2";
                    }
                    else if (numNO < 7 && numNO >= 4)
                    {
                        str = "AmurTiger_02";
                    }
                    else if (numNO <= 10 && numNO >= 7)
                    {
                        str = "Manticore_02";
                    }
                    break;
                }
        }
        return str;
    }
        
    //IEnumerator CreateEnemy() {
    //    while (true) {       
    //        yield return new WaitForSeconds(CreateSpeed);
    //        GameObject enemy = (GameObject)Resources.Load("Prefabs_Enemy/mon_goblinWizard");        
    //        enemy.GetComponent<EnemyContrl>().Pos = GameObject.FindGameObjectWithTag("WayPos");
    //        Instantiate(enemy);
    //    }     
    //}
}

很明显,我设置了很多public,这是方便在外部调试。首先我的想法是将怪物分成n个波次,每波m个怪物,后期可以选择关卡难度时可以改变,甚至可以每波数量递增。其次我们需要将自己需要的怪物名字写成何种形式,或枚举,或分支,总之可以在生成怪时可以控制每次生成的怪物是哪一个。最后,我们对脚本进行微调,如:若是飞行怪则出生高度拔高x单位,或为每一波怪物来临之前加上一个提示等等,随你喜欢。
当然,我们要在怪物的攻击动画中添加时间,在怪物攻击“水晶”或者“萝卜”的时候,扣除水晶一定血量,本游戏采取积分制,但是目前所有怪物死亡后加的分数相同,不便于分出高下,所以我便加了一个判断,假如怪物是被防御塔打死则加10分,被水晶打死则不得分,甚至扣分。
怪物生成逻辑就先告一段落,日后若有优化会开新篇,下一篇我们来探讨防御塔对怪物的检测以及各种子弹的逻辑。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容

  • 首先我们创建GameData脚本用来处理玩家的数据 然后我们创建DataAdpter脚本,用来数据本地化,即在游戏...
    貪狼大人阅读 352评论 0 2
  • 现在呢我们来搞一下防御塔对怪物的检测逻辑。首先呢,我想到了触发器检测,并配以一条列表储存在该防御塔射程内的所有敌人...
    貪狼大人阅读 429评论 0 1
  • 最近学习到了项目期,分配了组员之后,我们经过一番推敲,决定做一个塔防类型游戏,首先我们先建立了游戏场景(第一关)。...
    貪狼大人阅读 496评论 4 4
  • 秘密<纵火故事> 一、 小怪物—陈美 爷爷被人放火烧死了。 说起来,爷爷是跟我最亲的人了。9月27号这个日子就像...
    qx三生有幸阅读 862评论 3 5
  • /Users/wangyu/VMP/stb-ahsn/stb.keystore20131010mmtv.keystore
    止风者阅读 465评论 0 0