基于unity的google小恐龙游戏5----第四个BOSS

前言

上一篇文章我实现了第三个BOSS,蜂后,这个boss实际上跟眼珠子没有什么大区别,不过还是有一些需要斟酌写好的,无论是什么,就算他再简单也好,也总是有他的意义。我觉得搞这样的练习最重要还是体会过程,积累一些经验。最后总会有收获的。本来我是想写一些新的东西的,但是最后发现自己技术实在是有限,所以还是继续搞一下基础的,逐层递进。慢慢来。好了,开始本次练习记录。

Boss

一般来说,设计Boss肯定是要多设计几个小怪的,但是这次我直接设计这个boss,不设计太多小怪,这次选择的boss是来自泰拉瑞亚的克脑,这个boss的有趣的点就是他会让玩家陷入一个叫做“混乱”的异常状态。让玩家的方向键相反。这个似乎可以通过unity的刚体速度改变实现。先回顾一下我这个小恐龙的移动逻辑。

private Vector3[] direction = new Vector3[]{
        Vector3.right,Vector3.up,Vector3.left,Vector3.down
        };
    private KeyCode[] keys = new KeyCode[] {
        KeyCode.D,KeyCode.W,KeyCode.A,KeyCode.S
    };

上面这两段代码是我这个小恐龙移动的最基本的逻辑,通过两个数组,一个存放KeyCode,一个存放记录速度,那么只要设置一个for循环不断检查哪个按键按了,然后利用一个dirHeld变量,使得小恐龙直接获得一个对应的速度变量。

想法一:

 在Boss里面的脚本实现这个功能,由于unity里面对于输入流的检测是共通的,因此,我的第一个设想,是直接在Boss的脚本里面,检测输入,然后使其获得相反的速度。那样就可以得到一个混乱的效果。

Input.GetKey(KeyCode.A)------>dinoRig.velocity = Vector3.right;

想要以这样的方法实现,然后通过unity面板里面的脚本顺序设定其执行顺序,可能可以实现这样的效果。

但是最后以失败告终,无论怎么调节都好,都没有任何效果。最后发现这样的核心逻辑是错误的,因为unity对象的脚本并行执行的时候,无论如何都会是的dino的dirheld回到正确的按键,假设是Boss先,那么按键检测到,更改了速度,下一个恐龙脚本执行就会变回原来的速度,要是恐龙的脚本先执行,在后面Boss的脚本又跟改了速度,紧接着还是恐龙的脚本,而且在恐龙的脚本里面,每一次开始我都会把dirHeld重置为-1。

最后这个想法以失败告终

想法二:

现在是第二个想法,在恐龙的脚本里面添加一个isPlz的变量,检测是否处于混乱状态,如果是的话,那就检测dirheld,将对应的编号调转。那么就需要在Boss的脚本里面。将dino脚本实例化,这个耶不困难,因为,基本每一个Boss都保留则恐龙的实例化对象,只需要执行GetComponent这个泛化函数就可以了。

一开始的设想就是用if来执行,但是忽略了,if是顺序执行的,那么判断完前面后面那个依然会再次判断。

if(dirHeld==0){dirHeld=2;}

if(dirHeld==2){dirHeld=0;}

这就出现了无论如何都只会让dirHeld为0,不过可以直接通过goto?但是书上说goto不能乱用。

所以应该使用switch,而且switch的执行是 比较迅速的。代码修改为:

    switch(dirHeld)//改用switch
    {
            case 0:
            dirHeld = 2;
            break;
            case 2:
            dirHeld = 0;
            break;
            default:
            break;
    }
}

就这样,混乱效果就可以顺利执行了。

然后为了让玩家知道自己混乱了,就随便画了个?的图标,以及Boss释放混乱的信号:

使用的贴图图如下:

新小怪:飞眼

这个小怪本来在游戏里就是Boss的小弟,我也顺理成章地把他加进去,在游戏里,他会一直绕着Boss转,冲向玩家。但是冲向玩家地怪太多了。所以我模仿书里地实例,让他以左右飘动地形式从上往下移动,会配合Boss地混乱攻击。

这玩意实现比较简单直接上代码:

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

public class flyEyes : MonoBehaviour
{
    [Header("Set in Inspector")]
    private Rigidbody rig;
    public int facing;
    public float timePast;
    public float timeNow;
    // Start is called before the first frame update
    void Start()
    {
        rig = GetComponent<Rigidbody>();
        rig.velocity = Vector3.down;
        facing = 1;
        timeNow = Time.time;
        timePast = 1f;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 Pos = gameObject.transform.position;
        if (Pos.y <= 1f)
        {
            Destroy(gameObject);
        }
        if(Time.time - timeNow >= timePast)
        {
            timeNow = Time.time;
            rig.velocity = new Vector3(facing * 2f, -1, 0);
            if(facing == 1)
            {
                facing = -1;
            }
            else
            {
                facing = 1;
            }
        }

    }
}
 

 这是使用的贴图:

 Boss实现

这个boss不需要跟往常一样,盯着玩家或者转向。因为他本来就是对称的。

移动逻辑:在四个方向瞬移,并且不断向玩家靠近,靠近玩家到一定程度就会瞬移到别的地方。朝玩家靠近是为了阻挠玩家躲避,不是为了攻击。

攻击三个:分别是召唤五个小弟从天上飘下来

让玩家陷入混乱状态,并召唤三个小弟

跟三个分身夹击玩家。

实现都比较简单,而且这次我直接使用函数了,不像之前那样全部堆在update里面。

下面是代码:

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

public class KBrain : MonoBehaviour
{
    [Header("Set in Inspector")]
    public GameObject dino;
    public Vector3 dinoPos;//恐龙坐标恐龙位置
    public float timeNow;
    public float timeSum;
    public float timeLive;
    public float timePast;
    public GameObject brainShadow;//这个是对象
    public GameObject what;
    public GameObject flyEyes;//飞眼小弟
    public GameObject wavePre;//波
    public Vector3 standNext;
    public int roll;//技能选择
    public bool canMove;//是否可以到处移动
    public Rigidbody rig;//记录刚体
    private Vector2[] sumplace = new Vector2[] {
        new Vector3(5,5),new Vector3(5,-5),new Vector3(-5,5),new Vector3(-5,-5)
    };//需要使用到这个
    private Vector3[] transPlace = new Vector3[]
    {
        new Vector3(32.5f,8.4f,0),new Vector3(17.2f,8f,0),new Vector3(17.2f,2f,0),new Vector3(32.5f,2f,0)
    };//每过一次就瞬移到这个位置
    public Vector3 vel;
    private bool isRush;
    private bool isTrack;
    public Rigidbody dinoRig;
    public int sumNum;//记录影子的站位对应的数组
    public Vector3 sum;
    public int tranNum;
    public Vector3 flyPos;
    public bool isPlz;
    public bool hasPlz;
    public float plzzTime;
    private Vector3 Pos;
    public Dino dinoM;
    public int test;

    // Start is called before the first frame update
    void Start()
    {
        dino = GameObject.Find("dino");
        dinoPos = dino.transform.position;
        sum = new Vector3(32.5f, 8.4f, 0);
        gameObject.transform.position = sum;//一开始生成位置
        timeNow = Time.time;//获取初始时间
        timeSum = Time.time;
        timeLive = 60f;
        timePast = 3f;
        standNext = dinoPos;//这次的逻辑为一直向玩家靠近,到时间再换点
        vel = Vector3.zero;
        isRush = false;
        isTrack = false;
        rig = GetComponent<Rigidbody>();
        dinoRig = dino.GetComponent<Rigidbody>();
        canMove = true;
        tranNum = 0;
        flyPos = new Vector3(20f,9.5f,0);
        isPlz = false;
        hasPlz = false;
        plzzTime = 0;
        Pos = gameObject.transform.position;
        dinoM = dino.GetComponent<Dino>();
    }

    // Update is called once per frame
    void Update()
    {
        if(Time.time - timeSum >= timeLive)
        {
            GameObject wav = GameObject.Find("wave1(Clone)");
            if (wav != null)
            {
                Destroy(wav);
            }
            GameObject wat = GameObject.Find("what(Clone)");
            if (wat != null)
            {
                Destroy(wat);
            }
            dinoM.isPlz = false;
            Destroy(gameObject);
        }
        dinoPos = dino.transform.position;
        if (canMove == true)
        {
            Move();
        }
        if(Time.time - timeNow >= timePast)//这个是表示开始释放技能
        {
            Skill();
        }

    }
    void transNumPlus()
    {
        if(tranNum == 3)
        {
            tranNum = 0;
        }
        else
        {
            tranNum++;
        }
    }
    void Move()
    {
        dinoPos = dino.transform.position;
        standNext = dinoPos;//获得下一个目标
        Pos = gameObject.transform.position;
        if ((gameObject.transform.position - standNext).magnitude <= 2f||Pos.x>=33f||Pos.x<=16f)
        {//到达了目的地
            rig.velocity = Vector3.zero;
            gameObject.transform.position = standNext;//停止移动
            transNumPlus();
            gameObject.transform.position = transPlace[tranNum];

        }
        else
        {
            vel = standNext - gameObject.transform.position;
            vel.Normalize();
            rig.velocity = vel * 2f;
        }
    }
    void Skill()
    {
        canMove = false;
        switch(roll)//根据这个变量选择技能
        {
                case 0:
                for(int i = 0; i < 5; i++)
                {
                    GameObject flye = Instantiate(flyEyes);//生成flyeyes
                    Vector3 tem = flyPos;
                    tem.x += 2 * i;
                    tem.y += 0.5f * i;
                    flye.transform.position = tem;                   
                }
                canMove = true;
                timeNow = Time.time;//重置时间
                roll = Random.Range(0, 3);//一共三个技能
                break;
                case 1:
                if (isTrack == false)
                {
                    dinoPos = dino.transform.position;
                    standNext = dinoPos;standNext.y += 2f;
                    vel = standNext - gameObject.transform.position;
                    vel.Normalize();
                    rig.velocity = vel*5f;
                    isTrack = true;
                }
                if (isTrack == true)
                {
                    if((gameObject.transform.position - standNext).magnitude <= 0.1f)//到达目的位置
                    {
                        rig.velocity = Vector3.zero;
                        gameObject.transform.position = standNext;//固定位置
                        isPlz = true;
                    }
                    if (isPlz == true)
                    {
                        if (hasPlz == false)
                        {
                            GameObject plzWave = Instantiate(wavePre);//生成
                            Vector3 plztem = gameObject.transform.position;
                            for(int i = 0; i < 3; i++)
                            {
                                GameObject flp = Instantiate(flyEyes);
                                Vector3 tem = flyPos;
                                tem.x += 3 * i;
                                flp.transform.position = tem;
                            }
                            plztem.y += 1.5f;//使得对象显示在上面,目前不是很清楚图层咋用
                            plzWave.transform.position = plztem;
                            Instantiate(what);
                            plzzTime = Time.time;//获取时间
                            hasPlz= true;
                        }
                        GameObject wt = GameObject.Find("what(Clone)");
                        if (wt != null)//同步混乱符号
                        {
                            Vector3 tem2 = dino.transform.position;
                            tem2.x -= 0.12f;
                            tem2.y += 0.7f;
                            wt.transform.position = tem2;
                        }
                        dinoM.isPlz = true;//反转的方法修改为此
                        if(Time.time - plzzTime >= 5f)//时间到了
                        {//以下为重置改变过的的变量
                            Destroy(wt);
                            GameObject wave = GameObject.Find("wave1(Clone)");
                            if(wave != null)
                            {
                                Destroy(wave);
                            }
                            hasPlz = false;
                            isPlz = false;
                            isTrack = false;
                            timeNow = Time.time;
                            canMove = true;
                            dinoM.isPlz = false;
                            roll = Random.Range(0, 3);
                        }
                    }

                }
                break;
                case 2:
                if (isTrack == false) {

                    dinoPos = dino.transform.position;//获得恐龙坐标
                    Vector3 pppos = dinoPos;
                    pppos.x += sumplace[0].x; pppos.y += sumplace[0].y;
                    gameObject.transform.position = pppos;
                    vel = dinoPos - pppos;
                    vel.Normalize();
                    rig.velocity = vel * 5f;
                    isTrack = true;
                }
                if (isRush == false)
                {
                    for (int i = 1; i < 4; i++)
                    {
                        GameObject sdw = Instantiate(brainShadow);
                        Vector3 sp = dinoPos;
                        sp.x += sumplace[i].x; sp.y += sumplace[i].y;
                        sdw.transform.position = sp;
                        Rigidbody sr = sdw.GetComponent<Rigidbody>();
                        Vector3 sv = dinoPos - sp;
                        sv.Normalize();
                        sr.velocity = sv * 5f;
                    };
                    isRush = true;
                }
                Vector3 POS = gameObject.transform.position;
                if (POS.x <= 16f || POS.y <= 1f)
                {
                    isRush = false;
                    isTrack = false;
                    timeNow = Time.time;
                    canMove = true;
                    roll = Random.Range(0, 3);
                }
                break;
                
        }
    }
}
 

 这是使用的贴图:

 下面是效果图,还是不会传视频,是不是一定要把视频传上b站或者优酷才可以放在这里面啊,不是很懂。

test

 

上面是个视频,还没有加碰撞,所以是无敌的,虽然感觉效果不怎么样,但是作为练习,也让我有所收获了。我还会继续添加东西,但是快过年了,可能会休息一段时间,在这里拜个早年!祝大家新年快乐!万事如意 !谢谢大家的支持!

  • 52
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值