在敌人的预制体上选择合适的位置创建一个空对象,空对象的位置将用来挂载血条
在数据模板设置UpdateHealthBarOnAttack,第一个参数是当前血量,第二个则是最大血量
public event Action<int, int> UpdateHealthBarOnAttack;
UpdateHealthBarOnAttack?.Invoke(CurrentHealth, MaxHealth);
设置好数据模板后设置血条的代码再挂载在敌人上
public GameObject healthUIPrefab;//血条预制体
public Transform barPoint;//空对象的位置
public bool alwaysVisible;
public float visibleTime;//设置倒计时多少秒血条预制体显示关闭
private float timeLeft;
Image healthSlider;
Transform UIbar;
Transform cam;
CharacterStats currentStats;
void Awake()
{
//获取数据模板脚本
currentStats = GetComponent<CharacterStats>();
currentStats.UpdateHealthBarOnAttack += UpdateHealthBar;
}
private void OnEnable()
{
cam = Camera.main.transform;
foreach(Canvas canvas in FindObjectsOfType<Canvas>())
{
if(canvas.renderMode == RenderMode.WorldSpace)
{
//当前血条在画布的位置
UIbar = Instantiate(healthUIPrefab, canvas.transform).transform;
//使用GetChild()获取父物体下子物体的索引
healthSlider = UIbar.GetChild(0).GetComponent<Image>();
UIbar.gameObject.SetActive(alwaysVisible);
}
}
}
private void UpdateHealthBar(int currentHealth, int maxHealth)
{
if(currentHealth <= 0)
{
Destroy(UIbar.gameObject);//销毁血条
}
UIbar.gameObject.SetActive(true);
timeLeft = visibleTime;//攻击到敌人后倒计时
float sliderPercent = (float)currentHealth / maxHealth;//当前血量/最大血量
healthSlider.fillAmount = sliderPercent;//将数值赋值给绿色图片
}
void LateUpdate()//血条关闭计时
{
if(UIbar != null)
{
UIbar.position = barPoint.position;
UIbar.forward = -cam.forward;
if(timeLeft <= 0 && !alwaysVisible)//判断倒计时是否等于0
{
UIbar.gameObject.SetActive(false);//关闭血条显示
}
else
{
timeLeft -= Time.deltaTime;//继续倒计时
}
}
}