学习的时候负责写了关于怪物血量以及其血条显示的脚本,先上代码。
游戏内血量条的制作
1.先展示一下具体是怎么写的
两个Image文件拉成长方形条,并将该组合制作为预制体。
在Source Image中设置一个Squre,然后将Image Type设置为Filled(填充类型),而Fill Amount就可以控制血条的显示了!
使用了Dotween插件,完成了血量延迟减少的一个动画效果
这里是在2秒内,healthSlider.fillAmount的值(当前血量)变成sliderPercent(扣除伤害后的血量)
DOTween.To(() => healthSlider.fillAmount, x => healthSlider.fillAmount = x, sliderPercent, 2);//血量变化
挂载脚本
脚本如下,挂载在怪物游戏对象的身上
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; ////// 控制怪物血量条的展示和跟随 /// public class Healthbar_UI : MonoBehaviour { public GameObject HealthUIPrefab;//血条的预制体 public GameObject barpoint;//怪物的血条位置 Image healthSlider;//血量的滑动条 Transform UIbar;//血条位置 Transform cam;//摄像机位置 public bool alwaysVisible = false;//是否可见 public float visibleTime;//可见时长 private float TimeLeft;//剩余可见时长 private void OnEnable() { cam = Camera.main.transform;//挂载摄像机 UIbar = Instantiate(HealthUIPrefab,this.transform, barpoint).transform; healthSlider = UIbar.GetChild(1).GetComponent();//获取绿条 UIbar.gameObject.SetActive(false);//设置是否长久可见 healthSlider.fillAmount = 1;//初始血条为满 } private void LateUpdate() { //当UI不被销毁的时候,一直朝向摄像机的反方向(即面对摄像机) if (UIbar != null) { UIbar.position = barpoint.transform.position; UIbar.forward = -cam.forward; if (TimeLeft <= 0 && !alwaysVisible) { UIbar.gameObject.SetActive(false); } else { TimeLeft -= Time.deltaTime; } } } /// /// 控制血量展示 /// /// 当前的生命值 /// 最大血量 public void UpdateHralthBar( float currentHealth, float maxHealth) { //当血量归0时,摧毁血条 if (currentHealth <= 0) Destroy(UIbar.gameObject); TimeLeft = visibleTime;//每次重新攻击,血条显示时间都会重置 UIbar.gameObject.SetActive(true); //设置血量时,血条出现 float sliderPercent = currentHealth / maxHealth; DOTween.To(() => healthSlider.fillAmount, x => healthSlider.fillAmount = x, sliderPercent, 2);//血量变化 } }
怪物对应的血量脚本如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; ////// 修改怪物血量的脚本 /// public class MonsterHealth : MonoBehaviour { [Header("怪物生命值")] public float HP;//怪物的生命值 private float HP_MAX;//怪物最大生命值 private void Start() { HP_MAX = HP;//初始化怪物最大生命值 } //对于伤害进行判定 public void DamageJudge(string AttackedWeapon) { float before = 0; //受到什么样的武器攻击 switch (AttackedWeapon) { case "Weapon": AddHP(-3); AttackedWeapon = null;//将碰撞消息设置为空 break; case "Bullet": AddHP(-5); AttackedWeapon = null;//将碰撞消息设置为空 break; case "Attack3Effect": AddHP(-6); break; } this.GetComponentInChildren().UpdateHralthBar(HP, HP_MAX);//设置血条详情//设置血条详情 if (HP == 0) { Destroy(this.gameObject);//销毁自身 } } //增减怪物血量 public void AddHP(float value) { float Before = HP;//返回一个当前血量 HP += value; HP = Mathf.Clamp(HP, 0, HP_MAX);//保证血量只会削减到0(而不是负数) } }
PS.关于这里,像接收到碰撞器的消息后,应该从JSON文件中查找该武器,并检索其对应的攻击伤害并计算伤害值,而不是写一个简单的switch语句在这里,但是因为我暂时还没搞懂json表,有待优化。
完成效果
一个边界的判定代码(碰撞体和tag调用)
////// 检测是否掉出游戏边界的类 /// public class GameBoundary: MonoBehaviour { private void OnCollisionEnter(Collision collision) { //如果掉落下来的是玩家,就将玩家放回初始化位置 if (collision.gameObject.tag == "Player") { collision.gameObject.transform.position = new Vector3(5.7f, 0, 0); } else//销毁掉落到当前位置的其他对象(敌人) { Destroy(collision.gameObject); } } }



