(M)unity2D敌人的创建、人物属性设置,遇敌掉血

发布时间:2024年01月23日

敌人的创建

1.敌人添加与组件设置

1)添加敌人后,刚体添加,碰撞体添加(一个碰撞体使猪在地上走,不接触人,另一个碰撞体组件使人和猪碰在一起产生伤害)

①刚体
刚体添加

②碰撞体一

设置的只在脚下,只需要敌人可以站在场景中就可以
但存在添加碰撞体积后,会和其他移动的人物或敌人产生碰撞使得无法擦肩而过的效果,通过组件中的layer overrides解决敌人与player碰撞问题,通过触发器trigger解决人物碰到猪以后掉血的情况

在这里插入图片描述

layer overrides

注意低版本(譬如2022.1.24)unity编辑器在box collider组件中没有layer overrides,需要安装新的editor重新打开项目。版本可能不适应,换了许多版本editor,用最新的。

1.图层重载是指在layer中可以剔除掉不想发生碰撞的角色

在这里插入图片描述

2.添加两种图层类型

不需要与player和enemy产生碰撞,则增加这两种图层类型
在这里插入图片描述

3.选中敌人,赋值,同理选中玩家

在这里插入图片描述
4.给猪剔除这两种图层

在这里插入图片描述

trigger

③ 碰撞体二

猪是触发器,成为触发器后猪就没有碰撞体积了
可以触发到猪的不包含enemy,防止敌人之间相互碰撞产生伤害
在这里插入图片描述
添加代码测试触发器的触发

用方法OnTriggerStay2D

在这里插入图片描述

private void OnTriggerStay2D(Collider2D collision)
{
    Debug.Log(collision.name);
}

可见触发器在接触到没有被屏蔽的碰撞体时被触发了

在这里插入图片描述


解决报错

Screen position out of view frustum

方法:

增大摄像机的size
在这里插入图片描述


人物属性设置、遇敌掉血

1.代码创建

在人物与敌人身上都需要挂这个代码,用于记录人物最大血量与当前血量等属性

在这里插入图片描述例如

public class Character : MonoBehaviour
{
    [Header("基本属性")]

    public float maxHealth;
    public float currentHealth;
}

2.在每一次触发攻击时减少character中的当前血量

创建attack脚本

在这里插入图片描述
攻击属性一般包括伤害、攻击范围、攻击频率等,此次添加猪给人的接触伤害,挂在猪身上

猪的攻击,每次接触到人,就会持续被触发,触发后对触发者中扣血函数进行调用

public class Attack : MonoBehaviour
{
    public int damage;

    public float attackRange;

    public float attackRate;

    //作为触发器被别的碰撞体collition触发后,collition会扣血

    private void OnTriggerStay2D(Collider2D collision)
    {
        collision.GetComponent<Character>().TakeDamage(this); 
    }
}

player的受伤代码

public class Character : MonoBehaviour
{
    [Header("基本属性")]

    public float maxHealth;
    public float currentHealth;


    private void Start()
    {
        currentHealth = maxHealth;
    }
    //受伤
    public void TakeDamage(Attack attacker)
    {
        currentHealth = currentHealth - attacker.damage;
    }
}

3.扣血过多,计时器 设置一次受伤后触发无敌状态

Time.deltaTime: 时间的修正,完成上一帧所用的时间(s)

触发伤害过程:触发,检测是否为无敌状态
无敌状态:直接返回;
不是无敌状态,触发一次伤害,进入无敌状态,无敌状态计时器开始倒数,倒数到<=0,脱离无敌状态,此时又可以受伤害了。

public class Character : MonoBehaviour
{
    [Header("基本属性")]

    public float maxHealth;
    public float currentHealth;

    [Header("无敌状态")]
    //无敌时间
    public float invulnerableTime;
    //计时器
    private float invulnerableCounter;
    //状态
    public bool invulnerable;

    private void Start()
    {
        currentHealth = maxHealth;
    }

    //每次update都检测是否为无敌状态
    private void Update()
    {
        if (invulnerable)
        {
            invulnerableCounter -= Time.deltaTime;
            if (invulnerableCounter <= 0)
            {
                invulnerable = false;
            }
        }
    }

    //受伤
    public void TakeDamage(Attack attacker)
    {
        //如果无敌,则直接返回
        if (invulnerable)
        {
            return;
        }
        //Debug.Log(attacker.damage);
        currentHealth = currentHealth - attacker.damage;
        //触发一次伤害,就变成无敌
        triggerInvulnerable();
    }

    //触发无敌状态函数
    private void triggerInvulnerable()
    {
        if (!invulnerable)
        {
            invulnerable = true;
            invulnerableCounter = invulnerableTime;
        }
    }
}

对于以下代码,需要确定触发触发器的碰撞体上含有组件脚本Character,
如果对方没有这个脚本,在被触发时会报错

private void OnTriggerStay2D(Collider2D collision)
{
    collision.GetComponent<Character>().TakeDamage(this); 
}

解决方法:

添加对对方是否存在该组件的判断:

在这里插入图片描述


检测血量,扣血不要减到0还在减少,
增加判断,如果血量大于一次伤害,则扣血;如果不大于,则归零

public void TakeDamage(Attack attacker)
{
    //如果无敌,则直接返回
    if (invulnerable)
    {
        return;
    }
    if (currentHealth - attacker.damage > 0)
    {
        currentHealth -= attacker.damage;
    }
    else
        currentHealth = 0;
    
    //触发一次伤害,就变成无敌
    TriggerInvulnerable();
}
文章来源:https://blog.csdn.net/mimo_mimo/article/details/135676776
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。