血条(Health Bar)的预制设计
具体要求如下:
- 分别使用 IMGUI 和 UGUI 实现
- 使用 UGUI,血条是游戏对象的一个子元素,任何时候需要面对主摄像机
- 分析两种实现的优缺点
- 给出预制的使用方法
IMGUI实现
IMGUI.cs代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IMGUI : MonoBehaviour
{
public float health = 0.0f;// 当前血量
private float resulthealth;// 增/减后血量
private Rect HealthBar;
private Rect HealthUp;
private Rect HealthDown;
void Start()
{
//血条区域
HealthBar = new Rect(50, 50, 200, 20);
//加血按钮区域
HealthUp = new Rect(60, 80, 80, 20);
//减血按钮区域
HealthDown = new Rect(155, 80, 80, 20);
resulthealth = health;
}
void OnGUI()
{
if (GUI.Button(HealthUp, "HealthUp"))
{
resulthealth = resulthealth + 0.1f > 1.0f ? 1.0f : resulthealth + 0.1f;
}
if (GUI.Button(HealthDown, "HealthDown"))
{
resulthealth = resulthealth - 0.1f < 0.0f ? 0.0f : resulthealth - 0.1f;
}
//插值计算health值,以实现血条值平滑变化
health = Mathf.Lerp(health, resulthealth, 0.05f);
// 用水平滚动条的宽度作为血条的显示值
GUI.HorizontalScrollbar(HealthBar, 0.0f, health, 0.0f, 1.0f);
}
}
创建空对象IMGUI_HealthBar,将IMGUI.cs拖动到空对象上,运行效果如下:

按HealthUp按钮时血量增加,按HealthDown时减少。
UGUI实现
-
在场景中新建一个plane对象
-
导入游戏角色: 菜单 Assets -> Import Package -> Characters,导入资源
-
将游戏对象放入场景中
-
检查属性:
- Plane 的 Transform 的 Position = (0,0,0)
- 游戏对象的 Transform 的 Position = (0,0,0),Rotation = (0,180,0)
- Main Camera 的 Transform 的 Position = (0,1,-10)
-
给Player添加Canvas子对象:右击Ethan,选择UI,选择Canvas,Canvas属性如下:

-
选择Player的子对象Canvas,选择上下文菜单中UI的Slider,添加滑条作为血条子对象,Slider属性如下:

- 禁用Handle Slide Area
- 点击Fill,将Color改为红色

- Slider参数:


- 运行后发现血条能跟随游戏对象移动,但是不能一直朝向主摄像机,因此给Canvas添加脚本LookAtCamera.cs:
public class LookAtCamera : MonoBehaviour
{
// Update is called once per frame
void Update()
{
this.transform.LookAt(Camera.main.transform.position);
}
}
- 给Canvas添加一个血条的控制器HealthControl.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthControl : MonoBehaviour
{
public Slider mainSlider;// 血条
public float duration = 10;// 恢复血的时间的间隔
private float dur_time = 0;// 用于计时
private float health;// 当前血量
private float resultHealth;// 增/减后血量
private bool flag = false;// 增减血
void Start()
{
// 设置最大血量、最小血量、回血间隔以及现在血量
mainSlider.maxValue = 100;
mainSlider.minValue = 0;
duration = 10;
// mainSlider.wholeNumbers = true;
mainSlider.value = mainSlider.maxValue / 2;
health = mainSlider.value;
resultHealth = health;
}
void Update()
{
// 计时以回血
if (mainSlider.value < mainSlider.maxValue - 0.1 && !flag)
{
dur_time += Time.deltaTime;
if (dur_time >= duration)
{
resultHealth = mainSlider.value + 10 > mainSlider.maxValue ? mainSlider.maxValue : mainSlider.value + 10;
dur_time = 0;
}
}
// 发生碰撞,减血
else if (flag)
{
resultHealth = mainSlider.value - 20 < mainSlider.minValue ? mainSlider.minValue : mainSlider.value - 20;
flag = false;
}
// 平滑减少血量
health = Mathf.Lerp(health, resultHealth, 0.05f);
mainSlider.value = health;
// 控制slider中Fill Area的显示,以更符合血量的显示
if (mainSlider.value <= 0.01)
mainSlider.transform.GetChild(1).localScale = Vector3.zero;
else
mainSlider.transform.GetChild(1).localScale = Vector3.one;
}
// 外部控制减少血量
public void ReduceHealth()
{
flag = true;
}
}
- 将血条Slider添加到脚本HealthControl中

运行结果如下:

由于Pakage中没有Controller,这里手动改变游戏对象的位置和角度,可以发现血量条始终面对Main Camera。
分析两种实现的优缺点
IMGUI
优点:
- IMGUI 的存在符合游戏编程的传统
- 在修改模型,渲染模型这样的经典游戏循环编程模式中,在渲染阶段之后,绘制 UI 界面无可挑剔
- 既避免了 UI 元素保持在屏幕最前端,又有最佳的执行效率,一切控制掌握在程序员手中
- 如果不做复杂的界面,代码简单易用
缺点:
- 传统代码驱动的 UI 面临效率低下
- 难以调试等
UGUI
优点:
- 为了让设计师也能参与参与程序开发,从简单的地图编辑器、菜单编辑器等工具应运而生。 设计师甚至不需要程序员帮助,使用这些工具就可直接创造游戏元素,乃至产生游戏程序。
- 所见即所得(WYSIWYG)设计工具
- 支持多模式、多摄像机渲染面向对象的编程
- 面向对象的编程
- UI 元素与游戏场景融为一体的交互
预制的使用方法
- 直接将IMGUI-H-Bar预制体拖入场景
- 按照前面提到的方法导入资源,用预制体生成游戏对象Ethan,构建基本场景
- 将Canvas预制体拖入到Ethan对象,成为其子对象
- 将Canvas的子对象Slider拖入IMGUI-H-Bar对象的IMGUI.cs组件中的HealthSlider属性
- 运行后点击增/减血按钮即可实现两种血条的同时增/减血
675

被折叠的 条评论
为什么被折叠?



