Unity2D入门(九):敌人的移动、消灭敌人(包括动画的触发)

游戏中的敌人有三种,我们先拿青蛙和老鹰来做例子,我们要实现的效果是:青蛙要能共在一定的范围内往返跳动,老鹰则是在一定的范围内上下运动。

要实现敌人在一定范围内移动,拿青蛙为例,我们需要确定他活动的左右边界点,我们在frog下创建两个空物体,让他们分别代表左端点和右端点,在右侧Inspector窗口中,可以设置这个物体的颜色。

 

这样我就就可以依靠拖动两点的位置来界定敌人移动的边界了。

下一步我们在代码中实现敌人的移动,在这里我用文字阐述一下我的设计思想,首先为青蛙创建一个脚本,由于青蛙做往返运动,当青蛙面向左边时向左走,面向右边是向右走,当向左走碰到左端点是改变面部朝向,更改为向右走,通过上面描述,我们知道需要创建一个float类型的speed来控制青蛙的移动速度,在创建一个bool型的变量控制青蛙的面部朝向,假设用facing_left=true/false来控制面部朝向(初始值我们设为true)。接下来,代码运行时,我们首先要获取到做右端点的x的值,因此我们能需要两个变量来获取,获取了之后,这两个物体对于我们就是去了意义,留着只会浪费性能,所以我们要销毁这两个物体。接下来再考虑,青蛙是一跳一跳的,所以他还需要一个向上跳跃的力jumpforce,我们还需要为跳跃添加限制条件,每接触一次地面才能条一次,那不然就一直跳了。因此青蛙在运动中就会出现四种情况:1.面向左(在空中/不在空中)2.面向右(在空中/不在空中),下面直接上代码:

public class Enemy_frog : Enemy
{

    private Rigidbody2D rb;
    public Collider2D coll;
    public float speed,jumpforce;
    public LayerMask ground;
    public Transform leftpoint, rightpoint;
    private float leftx, rightx;
    private bool facing_left=true;
    //private Animator anim;

    protected override void Start()
    {
        base.Start();
        rb=GetComponent<Rigidbody2D>();
        //anim = GetComponent<Animator>();
        coll = GetComponent<Collider2D>();


        transform.DetachChildren();
        leftx = leftpoint.position.x;
        rightx = rightpoint.position.x;
       
        Destroy(leftpoint.gameObject);
        Destroy(rightpoint.gameObject);
    }

    // Update is called once per frame
    void Update()
    {
        SwitchAnim();
    }
    void Movement()
    {
        if (facing_left)
        {
            if (coll.IsTouchingLayers(ground))
            {
                anim.SetBool("jumping", true);
                rb.velocity = new Vector2(-speed, jumpforce);
            }
            if (transform.position.x<leftx)
            {
                rb.velocity = new Vector2(0, 0);
                transform.localScale = new Vector3(-1, 1, 1);
                facing_left = false;
            }
        }
        else
        {
            if (coll.IsTouchingLayers(ground))
            {
                anim.SetBool("jumping", true);
                rb.velocity = new Vector2(speed, jumpforce);
            }
            if (transform.position.x > rightx)
            {
                rb.velocity = new Vector2(0, 0);
                transform.localScale = new Vector3(1, 1, 1);
                facing_left = true;
            }
        }
    }
    void SwitchAnim()
    {
        if (anim.GetBool("jumping"))
        {
            if (rb.velocity.y < 0.1)
            {
                anim.SetBool("jumping",false);
                anim.SetBool("falling",true);
            }
        }
        if (coll.IsTouchingLayers(ground)&&anim.GetBool("falling"))
        {
            anim.SetBool("falling", false);
        }
    }

}

以上代码中有一些要注意的是这里用Collider变量去检测青蛙是不是和属于Grid瓦片地图发生了碰撞,这里瓦片地图要新建一个Layer取名为ground,另外动画的切换还存在一些问题,那就是这个青蛙根本不存在静止的状态,跳完一次之后紧接着开始第二次跳跃,我们希望他跳完一次后静止一段时间,才开始第二次跳跃,那么我们就需要用到在上节笔记中用到的动画event了,我们为青蛙创建了静止动画后,在静止动画结束的时候,为其添加两个事件,一个是Movement函数另一个是SwitchAnim函数,这样就是先了跳跃-静止-跳跃的过程。

老鹰的运动实现和青蛙的十分相似,而且更为简单,在此不做赘述。

下面来说一下消灭敌人的效果实现,因为敌人不只有一种,如果在每个敌人的脚本单独写消灭的效果也可以,但是会显得比较繁琐,所以我们可以为老鹰和青蛙添加一个共同的父类,在父类中写消灭敌人的效果,这样子类调用父类,就可以了。而且由于消灭敌人的效果我们是写在了Player Controller中,我们还要在其他的类中实现敌人类的实例化,代码:

public class Enemy : MonoBehaviour
{
    protected Animator anim;
    protected AudioSource deathAudio;
    // Start is called before the first frame update
    protected virtual void Start()
    {
        anim = GetComponent<Animator>();
        deathAudio = GetComponent<AudioSource>();
    }
    public void Death()
    {
        GetComponent<Collider2D>().enabled = false;
        Destroy(gameObject);
    }
    public void JumpOn()
    {
        deathAudio.Play();
        anim.SetTrigger("death");
    }

}

下面是在PlayerController中写道的消灭敌人的代码,两者需要结合着看,后面我来解释一下。

 private void OnCollisionEnter2D(Collision2D collision)
    {

        if (collision.gameObject.tag == "Enemy")
        {
            //eagle_test eagle = collision.gameObject.GetComponent<eagle_test>();
            //Enemy_eagle eagle = collision.gameObject.GetComponent<Enemy_eagle>();
            Enemy enemy = collision.gameObject.GetComponent<Enemy>();
            if (anim.GetBool("falling"))
            {
                enemy.JumpOn();
                //eagle.JumpOn();
                rb.velocity = new Vector2(rb.velocity.x, jumpforce * Time.fixedDeltaTime*50);
                anim.SetBool("jumping", true);
                anim.SetBool("falling", false);
            }else if (transform.position.x < collision.gameObject.transform.position.x)
            {
                rb.velocity = new Vector2(-10, rb.velocity.y);
                isHurt = true;
                hurtAudio.Play();
            }else if(transform.position.x > collision.gameObject.transform.position.x)
            {
                rb.velocity = new Vector2(10, rb.velocity.y);
                isHurt = true;
                hurtAudio.Play();
            }
        }
    }

 首先在Player代码中,如果碰撞体检测碰撞到tag标记为Enemy的物体,在继续判断,只有当角色处在下落的状态,也就是首先要碰到敌人,而且是在敌人的头顶,才能把敌人踩死,那么就去调用JumpOn函数,他的作用是出发名为death的动画,我们在来到Animator窗口中,我们可以看到一个看色的方块anystate,也就是说,在任何情况下都有可能出发的动画。那么这个动画触发了之后,我们在这个动画后添加event,首先先让他的active状态变为false,不然他只是切换了动画,他的碰撞体还在,会持续与游戏场景中的其他物体碰撞,然后再销毁它。重点是,在Player的代码中,通过 Enemy enemy = collision.gameObject.GetComponent<Enemy>();这一行代码实现了类的调用和实例化。

没有提及到的代码的功能是,如果消灭了敌人,玩家可以获得一次额外的跳跃,否则,如果不是踩在敌人头上,那么就是受伤,会被敌人击退,所以另外两个else是向两个方向击退的效果。

以上是以青蛙作为例子,老鹰的实现过程也是类似的,在此不做赘述。

 

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity2D中,实现敌人受伤以及死亡动画可以通过以下步骤进行: 1. 创建敌人动画控制器:在Assets面板中右键点击空白处,选择Create -> Animator Controller,命名为EnemyAnimator。 2. 添加动画状态:将敌人的受伤和死亡动画导入到Unity中,并在Animator视图中添加动画状态。受伤和死亡动画分别添加到两个不同的状态。 3. 添加参数:在Animator视图中,点击Parameters选项卡,添加两个参数,一个是trigger类型的Hurt,一个是bool类型的Dead。 4. 连接状态和参数:将Hurt参数连接到受伤状态的转换条件,将Dead参数连接到死亡状态的转换条件。 5. 编写代码:在敌人的脚本中,添加受伤和死亡的相关代码。当敌人受到攻击时,调用Hurt方法,该方法会触发Hurt参数,进而播放受伤动画;当敌人生命值为0时,调用Die方法,该方法会触发Dead参数,进而播放死亡动画。 示例代码: ```csharp public class Enemy : MonoBehaviour { public int health = 100; // 敌人生命值 private Animator animator; void Start() { animator = GetComponent<Animator>(); } public void Hurt(int damage) { health -= damage; if (health <= 0) { Die(); } else { animator.SetTrigger("Hurt"); } } private void Die() { animator.SetBool("Dead", true); // 禁用敌人的碰撞体和脚本 GetComponent<Collider2D>().enabled = false; GetComponent<Enemy>().enabled = false; } } ``` 以上就是实现敌人受伤以及死亡动画的基本步骤和示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值