游戏开发日志10(敌人血条跟随及动画适配)

由于要使得血条跟随敌人,我把血条UI设置为敌人的子级,并赋值给每个敌人。

要使敌人被击中后相应的减少血量,MaxValue和Value就不需要序列化了,所以我把它们设为了private,然后在Change函数里传入子弹的伤害值DanmageValue就行了,但是有一个问题,子弹是未实例化的,所以要将DanmageValue设为static,如果在Update函数里调用还要去判断是否trigger,不如直接在子弹的脚本里调用Change更省事。

public class EnemyBar : MonoBehaviour
{

    private int MaxValue;
    private int Value;

    [SerializeField]
    private RectTransform white;

    [SerializeField]
    private RectTransform red;

    [SerializeField]
    private float _animationSpeed = 10f;

    private float _fullWidth;
    private float TargetWidth => Value * _fullWidth / MaxValue;

    private Coroutine _adjustBarWidthCoroutine;

    private void Start()
    {
        MaxValue = GetComponentInParent<EnemyController>().hp;

        _fullWidth = red.rect.width;
    }



    public void Change(int amount)
    {
        Value = Mathf.Clamp(Value + amount, 0, MaxValue);
        if (_adjustBarWidthCoroutine != null)
        {
            StopCoroutine(_adjustBarWidthCoroutine);  //关闭上一次的协程
        }

        _adjustBarWidthCoroutine = StartCoroutine(AdjustBarWidth(amount)); 
    }

   

    private IEnumerator AdjustBarWidth(int amount)
    {
        var suddenChangeBar = amount >= 0 ? white : red;
        var slowChangeBar = amount >= 0 ? red : white;

        suddenChangeBar.setWidth(TargetWidth);

        while(Mathf.Abs(suddenChangeBar.rect.width-slowChangeBar.rect.width)>0.1f)
        {
            slowChangeBar.setWidth(Mathf.Lerp(slowChangeBar.rect.width, TargetWidth,
                Time.deltaTime * _animationSpeed));
            yield return null;  //下一帧再执行下一次循环,直到循环结束
        }
        slowChangeBar.setWidth(TargetWidth);

        //yield return 0;
    }
}



public static class RectTransformExtension
{
    public static void setWidth(this RectTransform t,float width)
    {
        t.sizeDelta = new Vector2(width, t.rect.height);
    }
}
private void OnCollisionEnter2D(Collision2D collision)
    {
        EnemyController enemyController = collision.gameObject.GetComponent<EnemyController>();

        if(enemyController!=null)
        {
            if(GameObject.Find(" 齿轮增强器").GetComponent<GearEnhance>().enabled)
            {
                DamageValue += 9;
            }
            else
            {
                DamageValue = 1;
            }
            collision.gameObject.GetComponentInChildren<EnemyBar>().Change(-DamageValue);
            enemyController.hp= enemyController.hp-DamageValue;
            if(enemyController.hp<=0)
            {
                enemyController.Fix();
            }           
        }

        Destroy(gameObject);
    }   

测试后还是发现了一个问题:敌人被击一次血条就见底。

于是我要看看MaxValue和Value的值

 private void Start()
    {
        MaxValue = GetComponentInParent<EnemyController>().hp;
        Debug.Log(MaxValue+"/"+Value);
        _fullWidth = red.rect.width;
    }

原来是Value忘了赋值,在后面添加一句Value = MaxValue;就好了 

在敌人被修复后关闭血条

很简单只需要两行:    public GameObject Bar;        Bar.SetActive(false);

再把canvas_EnemyBar赋值给Bar就行了。

明天我会创造一个更强的Boss,拥有更厚的血量,并且被击的部位不同受到的伤害也不同,攻击力更强且有一个强大的技能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值