您当前的位置: 首页 >  游戏

真的没事鸭

暂无认证

  • 3浏览

    0关注

    75博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

unity2D横板游戏教程6-敌人AI以及受击动画

真的没事鸭 发布时间:2022-08-02 20:46:57 ,浏览量:3

这节实现敌人AI的效果

为了保证代码的复用性,所以我们这里创建一个敌人父类,之后所有的敌人类都继承之这个敌人父类

先创建一个敌人父类脚本,命名为Enemy

e7df457732774309abc0f5d5697ed508.png

 然后简单写一下Enemy代码

6f641779fdb8465eae7f1decf7cf1467.png

 这里运用了虚函数,函数前面加上visual表示这个函数是虚函数。这里简单说一下什么是虚函数

虚函数是面向对象语言中多态性的重要实现. 当一个函数方法在声明时, 前面带了virtual关键字, 这个函数就是一个虚函数. 它与非虚函数的主要区别在于它的实现可以在派生类中进行重写(override)(非强制要求). 重写后的函数一样也是虚函数, 当一个类或其基类中存在虚函数后就不允许出现同名, 返回值, 参数类型个数相同的非虚函数。

想仔细了解的话可以找一些文章看,这里就不赘述了。

然后我们创建玩敌人父类之后我们就要创建敌人了

我们先在Hierarchy栏创建一个空组件命名为Enemies,表示敌人集合,然后创建一个空的子组件命名为Enemy_Frog,剩下的操作这里就不赘述了,和角色的创建是一样的,我们这里选择角色素材包那里的青蛙

913d94aef0924ed7873eb915943aefae.png

 不过记得改变它的图层,改成之前创建的Enemy,不然会显示不出来

同样添加collider和Rigidbody

93c95e9c0e424994baddacf982606fb8.png

 然后就是让敌人动起来

我们给敌人添加一下动画,和人物一样,这里不再赘述,为了方便管理,我们在Animation文件夹里新建一个文件夹Enemy来保存我们敌人的动画资源

这里我们只做了idle和run的动画即可,然后我们在Animator设置动画间的转换

c4d659491e7245cf8600ee2da896c28d.png

 用一个bool变量控制即可,run为true时切换成run动画,run为false切换成idle动画

然后我们设置一下敌人移动的边界,这个和角色检测是否碰到地面给角色添加一个checkground是一样的操作,我们给Enemy_Frog添加两个空组件,分别命名为left和right,分别表示青蛙可以移动的左右边界,然后我们调整一下位置

6a80db4e72fe43e89e7f6396ced58043.png

 然后我们给Enemy_Frog写一下脚本来控制它的行动,新建一个C#文件之后直接拖给Enemy_Frog即可

303c02f5eabc4870a233e5b60f0757f1.png

 我们打开脚本,照例先获得collider,rigidbody等引用,注意Enemy_Frog要继承Enemy类,而且重载了虚函数Start,所以Start函数前面要加上override

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

public class Enemy_Frog : Enemy
{
    private Collider2D coll;
    private Rigidbody2D rb;
    public int speed;
    //---------上面照旧----------
    public Transform left, right;//左边边界的引用
    private float leftMargin, rightMargin;//Frog可以移动的左右边界
    private bool faceRight=true;//开始青蛙是面向右的

    protected override void Start()
    {
        base.Start();//调用父类的Start函数
        coll = GetComponent();
        rb = GetComponent();
        //分别获得左右边界位置的x轴的大小
        leftMargin = left.position.x;
        rightMargin = right.position.x;
        //防止左边边界跟随敌人移动,获得后直接销毁
        Destroy(left.gameObject);
        Destroy(right.gameObject);
    }

    void Update()
    {
        Movement();
    }

    //基础移动
    void Movement()
    {
        //如果面向右
        if(faceRight)
        {
            anim.SetBool("run", true);
            rb.velocity = new Vector2(speed, rb.velocity.y);
            //当敌人超过右边界时
            if (transform.position.x > rightMargin)
            {
                rb.velocity = new Vector2(0, 0);
                transform.localScale = new Vector3(-1, 1, 1);
                faceRight = false;
            }
        }
        else
        {
            anim.SetBool("run", true);
            rb.velocity = new Vector2(-speed, rb.velocity.y);
            //当敌人越过左边界时
            if(transform.position.x rightMargin)
            {
                rb.velocity = new Vector2(0, 0);
                transform.localScale = new Vector3(-1, 1, 1);
                faceRight = false;
            }
        }
        else
        {
            anim.SetBool("run", true);
            rb.velocity = new Vector2(-speed, rb.velocity.y);
            //当敌人越过左边界时
            if(transform.position.x 0)
        {
            isJump = true;
        }
    }
    private void FixedUpdate()
    {
        isGround = Physics2D.OverlapCircle(groundCheck.position, 0.1f, ground);
        if(!isHurt)
        {
            Movement();
        }
        Jump();
        SwitchAnim();
    }

    //基础移动
    void Movement()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);//设置x轴的移动
        //设置角色的转向问题
        if (horizontal != 0)
        {
            transform.localScale = new Vector3(horizontal, 1, 1);
            anim.SetBool("run", true);
        }
        else
            anim.SetBool("run", false);
    }

    //跳跃
    void Jump()
    {
        //如果在地面设置二段跳
        if (isGround)
        {
            jumpCount = 2;
        }
        //按下跳跃键且在地面上
        if (isJump && isGround)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
            jumpCount--;
            isJump = false;
        }
        //按下跳跃键且不在地面上且jumpCount大于0
        else if (isJump && !isGround && jumpCount > 0)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
            jumpCount--;
            isJump = false;
        }
    }

    //切换动画
    void SwitchAnim()
    {
        //如果在下落状态
        if (rb.velocity.y < 0 && !isGround)
        {
            anim.SetBool("fall", true);
            anim.SetBool("jump", false);
        }
        //如果在跳跃状态
        if (!isGround && rb.velocity.y > 0)
        {
            anim.SetBool("jump", true);
        }
        //如果人物受击
        else if (isHurt)
        {
            anim.SetBool("hurt", true);
            if (Mathf.Abs(rb.velocity.x) < 0.1f)
            {
                anim.SetBool("hurt", false);
                isHurt = false;
            }
        }
        //如果在地面上
        else if (coll.IsTouchingLayers(ground))
        {
            anim.SetBool("fall", false);
        }   
    }

    //判断是否碰到物品
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.tag=="Collection")
        {
            Destroy(collision.gameObject);
            cherries++;
            cherryText.text = "樱桃:" + cherries;
        }
    }

    //消灭敌人
    private void OnCollisionEnter2D(Collision2D collision)
    {
        //判断是否碰到敌人
        if(collision.gameObject.tag=="Enemy")
        {
            //消灭敌人
            Enemy enemy = collision.gameObject.GetComponent ();//获得敌人父类引用
            if(anim.GetBool("fall"))//判断是否下落跳到敌人头上消灭敌人
            {
                enemy.Death();//调用父类函数
                rb.velocity = new Vector2(rb.velocity.x, jumpForce);
                anim.SetBool("jump", true);
            }
            //如果人物在敌人的左边
            else if(transform.position.xcollision.gameObject.transform.position.x)
            {
                rb.velocity = new Vector2(8, rb.velocity.y);
                isHurt = true;
            }
        }
    }
}

如有错漏之处,欢迎指正!

 

关注
打赏
1663134582
查看更多评论
立即登录/注册

微信扫码登录

0.3258s