【Unity exam01】怎样制作一个血条栏
怎样制作一个血条栏?
普通血条栏:
渐变色血条栏:
缓冲血条栏:
3D场景血条栏跟随玩家移动:
【参考视频】
url:YouTube - How to make a Health BAR in Unity!
url:bilibili -【中文字幕】Unity血条UI设计和受伤缓冲效果
一、制作UI
-
在Canvas下创建一个空物体HP bar,在空物体下方创建3个Image,分别为血条框bar 黑色,最大HP maxHP 白色,和当前HP currentHP 红色。(PS:注意先后顺序以调整显示的图层)
效果:(PS:这里最大HP,即白色部分与红色部分重合没有显示) -
点击HP bar,添加slider(滑块)组件,进行以下设置,最小值和最大值可以关联血量自行调整。当拖动Value值时,就能实现改变血条的宽度。
效果:拖动Value值 -
创建一个脚本HPbar,拖拽给空物体HP bar
public class HPbar: MonoBehaviour
{
public Slider slider; // 获得Slider对象
public void SetHP(int currentHP)
{
// 设置slider的value为当前血量
slider.value = currentHP;
}
public void SetMaxHP(int maxHP)
{
// 设置slider的最大值,并设置value为最大血量
slider.maxValue = maxHP;
slider.value = maxHP;
}
}
- 创建一个Cube,作为玩家Player进行测试,新建一个玩家脚本Player
public class Player: MonoBehaviour
{
[Header("健康参数")]
[SerializeField]
int maxHP = 100; // 最大血量
[SerializeField]
int currentHP; // 当前血量
public HPbar bar; // 获得HPbar组件引用
private void Start()
{
// 游戏开始时,初始化血量
currentHP = maxHP;
// 设置slider的maxvalue和value值
bar.SetMaxHP(maxHP);
}
private void Update()
{
// 按下空格血量-20
if (Input.GetKeyDown(KeyCode.Space))
{
GetDamage(20);
}
}
void GetDamage(int damage)
{
// 减少血量
currentHP -= damage;
// 重新为slider的value赋值为当前血量
bar.SetHP(currentHP);
}
}
- 运行Unity,按下空格就可以看到血量条的UI在根据玩家的血量对应的减少了,到这里就基本实现了血条栏的制作。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201023211055816.gif#
【extra skill 额外技巧】
一、怎样实现血量的渐变功能?
(1)在HPbar脚本下新增一行公共的渐变类型变量
public Gradient gradient; // 渐变类型变量
打开UNITY,点击Gradient的值,弹出一个界面
选择Mode模式为Fixed,因为我们想要的是完全填充的效果而不是混色
选择下方蓝色区域的箭头,或点击空白地方添加新区域
我的Location设置为红色20%,黄色50%,绿色100%,意为玩家100血时血条为绿色,50时血条为黄色,20时血条为红色
(2)返回HPbar脚本,声明一个Image变量来调用currentHP的UI对象的引用
在SetMaxHP方法中,设置满血时血条的颜色为绿色
public Image HP; // 血量的UI
public void SetMaxHP(int maxHP)
{
// 设置slider的最大值,并设置value为最大血量
slider.maxValue = maxHP;
slider.value = maxHP;
// 当前血量UI的颜色为 gradient渐变颜色为绿色
// 此时slider.value为1,表示绿色
HP.color = gradient.Evaluate(slider.value);
}
在SetHP方法中,要根据当前血量来设置颜色的变换
public void SetHP(int currentHP)
{
// 设置slider的value为当前血量
slider.value = currentHP;
// HP的值为0到100,而渐变的值为0到1,所以要用到slider.normalizedValue将HP值归一化
HP.color = gradient.Evaluate(slider.normalizedValue);
}
(3)返回UNITY,别忘了将变量HP赋值为currentHP(红色的那条)
(4)实现效果
二、怎样实现血条缓冲效果?
(1)新建一个空物体,取名为Slow HP,在下方新建一个Image,取名为HP,这个HP为正常显示的HP。
**
这里介绍另一种方式血条滑动的方法:
**
1.点击Source Image,随意选择一种Sprite(有素材的可以直接添加素材图片作为Sprite),我选了第一个Background,颜色调为红色
若不喜欢边缘的润化,可以使用Material改变材质
2.将Image Type改为Filled填充类型,基于可以设置一系列参数,
现在拖动Fill Amount即可实现血条的滑动。
3.复制一份HP,取名为slowHP,作为缓冲血量,颜色为暗红色,rgb(100,0,0),并将Z坐标改为0.1使其显示在HP下层(PS:这里只做演示,有素材图片可修改sprite图层,非必要情况下最好不要修改通过修改Z轴坐标改变图层显示)
4.创建一个Image,填充为黑色,Z轴为0.2,其他不做任何改变
5.新建一个脚本SlowHP,拖拽给空物体Slow HP
public class SlowHP: MonoBehaviour
{
public Image HP; // 即时血量UI
public Image slowHP; // 缓冲血量UI
public Player player; // 玩家引用
private void Update()
{
// 血量的填充值为 当前HP/最大HP,并转换为float型
// 如当前HP为80,最大HP为100,则填充值 fillAmount为0.8
HP.fillAmount = (float)player.currentHP / (float)player.maxHP;
// 当缓冲血量大于即时血条时,缓冲血条持续减少
if (slowHP.fillAmount > HP.fillAmount)
{
// 缓冲血量持续减少,Time.daltaTime可换成其他时间参数,如0.01f
slowHP.fillAmount -= Time.deltaTime;
}
else
{
// 使缓冲血量与即时血量相等
slowHP.fillAmount = HP.fillAmount;
}
}
}
Slow UP脚本的引用
6.实现效果
三、怎样实现血条跟随玩家移动(广告牌效果)?
(1)复制一份之间的场景,要想让画布在世界坐标显示,就要将渲染改为世界坐标,并放入用来渲染的摄像机Camera
(2)调整Canvas的大小,将其作为player的子物体,跟随玩家移动
(3)编写一个简单的玩家移动的方法
public class Player: MonoBehaviour
{
[Header("移动参数")]
[SerializeField]
float speed;
float hor;
float ver;
[Header("健康参数")]
public int maxHP = 100; // 最大血量
public int currentHP; // 当前血量
public HPbar bar; // 获得HPbar组件引用
private void Start()
{
// 游戏开始时,初始化血量
currentHP = maxHP;
// 设置slider的maxvalue和value值
bar.SetMaxHP(maxHP);
}
private void Update()
{
// 按下空格血量-20
if (Input.GetKeyDown(KeyCode.Space))
{
GetDamage(20);
}
hor = Input.GetAxisRaw("Horizontal");
ver = Input.GetAxisRaw("Vertical");
}
private void FixedUpdate()
{
MoveMent();
}
void GetDamage(int damage)
{
// 减少血量
currentHP -= damage;
// 重新为slider的value赋值为当前血量
bar.SetHP(currentHP);
}
void MoveMent()
{
transform.Translate(new Vector3(hor * speed, 0, ver * speed));
}
}
(4)为了方便测试血条是否一致朝向摄像机,我们队摄像机编写代码使它能够围绕某个点进行公转。创建一个空物体作为摄像机公转中心,然后新建脚本CameraMove
public class CameraMove: MonoBehaviour
{
[SerializeField]
Transform point;
[SerializeField]
float speed;
private void FixedUpdate()
{
transform.RotateAround(point.position, Vector3.up, speed * Time.fixedDeltaTime);
}
}
(5)创建一个新脚本,取名为Billboard(广告牌),拖拽给血条HP bar,为了测试使用了Gizmos描线工具
public class Billboard: MonoBehaviour
{
public Transform camara;
private void LateUpdate()
{
transform.LookAt(camara.position);
}
private void OnDrawGizmos()
{
Gizmos.DrawLine(transform.position, camara.position);
}
}
保存运行unity,发现在Game窗口血条的确是时刻朝向了摄像机,但是在Scene面板中可以发现,血条框一直在进行自转,这样是不正确的。
(6)血条应该朝向 自身的位置 + 摄像机的向前的向量,这里我暂时也不太明白,可以根据Gizmos描线工具进行研究
public class Billboard: MonoBehaviour
{
public Transform camara;
private void LateUpdate()
{
transform.LookAt(camara.transform.position + camara.forward);
}
private void OnDrawGizmos()
{
Gizmos.color = Color.green;
Gizmos.DrawLine(transform.position, transform.position + camara.forward);
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, camara.position);
}
}
实现效果
·完整项目百度云
https://pan.baidu.com/s/1G6_vV1X7jTyMetGZfP7UVw
提取码:w93f
Unity版本:2019.4.3及以上
日期:2020-10-24
本文地址:https://blog.csdn.net/qq_43190977/article/details/109247893
上一篇: 张量分解浅谈(二 CP NMF 张量秩)
下一篇: 荣耀10青春版的主要参数与特性