Damageable.cs

来源:互联网 发布:gamemaker 源码 编辑:程序博客网 时间:2024/06/03 13:31
using UnityEngine;using System.Linq;using System.Collections;using System.Collections.Generic;public class Damageable : MonoBehaviour{    public const string BloodbarTexture = "Texture/attach/color/blank";    public enum ESpecialState { Normal, Invincibility, Bleeding }//特殊状态枚举: 正常,无敌,流血    public float Health = 100;//自身生命值上限    public float Damage = 0;//攻击时伤害值    public float DamageSec = 0;//持续攻击(例如流血)时间    public ESpecialState SpecialState = ESpecialState.Normal;//默认为普通状态    public bool CanSelfdestruct = true;//默认可以自毁,在特定情况下自毁由动画实体处理,所以此选项根据需要自由设定    public bool IsShowBloodbar = false;//默认不显示血条    public Color BloodbarColor = Color.red;//血条默认红色    public float CurrentHealth { get; private set; } //获取当前生命值    public float HealthPercent { get { return CurrentHealth / Health; } }//获取生命值百分比    public bool IsAlive { get; private set; }    static Texture m_Bloodbar;    static UIRoot m_Root;    static Camera m_Camera;    float m_getHurt;//受到伤害值,用于计算持续伤害    float m_getHurtSec;//受到伤害持续时间    GameObject m_bloodbar;    #region 静态函数    //判断是否有攻击组件    public static bool IsHasComponent(GameObject target)    {        var result = false;        try        {            if (target.GetComponent<Damageable>() != default(Damageable)) result = true;        }        catch        {            result = false;        }        return result;    }    //判断是否可攻击    public static bool IsCanHurt(GameObject target)    {        var result = false;        try        {            if (target.GetComponent<Damageable>().SpecialState != ESpecialState.Invincibility) result = true;        }        catch        {            result = false;        }        return result;    }    //找到所有可攻击目标    public static List<Damageable> GetAllTargetList()    {        return ((Damageable[])FindObjectsOfType(typeof(Damageable))).ToList();    }    //获取指定标签匹配的攻击列表    public static List<Damageable> GetTargetList(string targetTag)    {        return GetAllTargetList().FindAll(t => t.tag.Equals(targetTag));    }    //获取所有标签匹配的攻击列表    public static List<Damageable> GetTargetList(string[] targetTags)    {        var getList = GetAllTargetList();        var targetList = new List<Damageable>();        for (var i = 0; i < targetTags.Length; i++)        {            targetList.AddRange(getList.FindAll(t => t.tag.Equals(targetTags[i])));        }        return targetList;    }    //判断目标是否在攻击列表内,必须是同类型才可以判断    public static bool HasTargetListIncludeThis(Damageable currentTarget, List<Damageable> targetList)    {        return targetList.Contains(targetList.Find(t => t.GetInstanceID().Equals(currentTarget.GetInstanceID())));    }    //根据当前位置和搜索范围过滤攻击列表    public static List<Damageable> GetAreaDamageFilter(List<Damageable> targetList, Vector3 position, float searchRange)    {        var damageList = new List<Damageable>();        for (var i = 0; i < targetList.Count; i++)        {            var myPos = m_Camera.WorldToScreenPoint(position);            var targetPos = m_Camera.WorldToScreenPoint(targetList[i].transform.position);            var distance = (targetPos - myPos).magnitude;            if (distance < searchRange)            {                damageList.Add(targetList[i]);            }        }        return damageList;    }    //伤害结算    public static void HurtAccount(List<Damageable> damageList, float damage)    {        for (var i = 0; i < damageList.Count; i++)        {            damageList[i].Hurt(damage);        }    }    #endregion    #region 系统调用    void Awake()    {        m_Bloodbar = Resources.Load<Texture>(BloodbarTexture);    }    void Start()    {        //设置相机        m_Root = FindObjectOfType<UIRoot>();        m_Camera = m_Root.transform.FindChild("Camera").GetComponent<Camera>();        //初始化参数        IsAlive = true;//默认存活        Health = Mathf.Abs(Health);//默认以绝对值为生命值点数以防止输入为负数情况        CurrentHealth = Health;//初始化当前生命值        m_getHurt = 0;        m_getHurtSec = 0;        //删除现有血条        try        {            m_bloodbar = transform.FindChild("bloodbar").gameObject;            m_bloodbar.transform.SetParent(null);            DestroyObject(m_bloodbar);        }        catch        {            m_bloodbar = null;        }        //判断是否显示血条        if (IsShowBloodbar)        {            var sprite = GetComponent<UISprite>();            m_bloodbar = new GameObject("bloodbar");            m_bloodbar.transform.SetParent(transform);            m_bloodbar.transform.localScale = Vector3.one;//设置尺寸            m_bloodbar.layer = transform.parent.gameObject.layer;            m_bloodbar.AddComponent<UITexture>();            m_bloodbar.GetComponent<UITexture>().mainTexture = m_Bloodbar;            m_bloodbar.GetComponent<UITexture>().width = sprite.width;            m_bloodbar.GetComponent<UITexture>().height = 15;            m_bloodbar.GetComponent<UITexture>().type = UIBasicSprite.Type.Filled;            m_bloodbar.GetComponent<UITexture>().fillDirection = UIBasicSprite.FillDirection.Horizontal;            m_bloodbar.GetComponent<UITexture>().color = BloodbarColor;            m_bloodbar.transform.localPosition = new Vector2(0, (float)(sprite.height + m_bloodbar.GetComponent<UITexture>().height) / 2);            m_bloodbar.SetActive(true);            StartCoroutine(delayHideBloodbar());//开启协程        }        else        {            if (m_bloodbar != default(GameObject)) m_bloodbar.SetActive(false);            StopCoroutine(delayHideBloodbar());//关闭协程        }    }    void Update()    {        if (CurrentHealth > 0)        {//判定为存活            if (m_getHurtSec > 0)            {//有未结算的持续伤害                var sec = Time.deltaTime;                m_getHurtSec -= sec;//结算持续伤害时间                var hurt = Mathf.RoundToInt(m_getHurt / m_getHurtSec / sec);                m_getHurt -= hurt;//结算剩余伤害                CurrentHealth -= hurt;//结算当前生命值            }        }        else        {//判定为死亡            Killed();//死亡结算        }    }    #endregion    #region 伤害结算    //摧毁处理    void OnDestroy()    {        IsAlive = false;        gameObject.tag = "Untagged";    }    //一次性伤害    public void Hurt(float damage)    {        if (SpecialState == ESpecialState.Invincibility) return;//无敌时退出        CurrentHealth -= damage;//直接扣除伤害值        if (IsShowBloodbar) showBloodbar();    }    //持续性伤害    public void Hurt(float damage, float damageSec)    {        if (SpecialState == ESpecialState.Invincibility) return;//无敌时退出        m_getHurt += damage;//叠加伤害        m_getHurtSec += damageSec;//叠加时间        if (IsShowBloodbar) showBloodbar();    }    //击杀结算    public void Killed()    {        IsAlive = false;        CurrentHealth = 0;        m_getHurt = 0;        m_getHurtSec = 0;        SpecialState = ESpecialState.Normal;        if (CanSelfdestruct) DestroyObject(gameObject);    }    #endregion    #region 血条处理    //显示血条    void showBloodbar()    {        if (!IsAlive || m_bloodbar == default(GameObject)) return;        m_bloodbar.GetComponent<UITexture>().fillAmount = HealthPercent;//实时读取血条        m_bloodbar.SetActive(true);        delayHideBloodbar();    }    //等待2秒后隐藏血条    IEnumerator delayHideBloodbar()    {        while (IsAlive)        {            yield return new WaitForSeconds(2);            try            {                m_bloodbar.SetActive(false);            }            catch            {                // ignored            }        }    }    #endregion}

0 0
原创粉丝点击