作业九
要求
- 分别使用 IMGUI 和 UGUI 实现
- 使用 UGUI,血条是游戏对象的一个子元素,任何时候需要面对主摄像机
- 分析两种实现的优缺点
- 给出预制的使用方法
UGUI实现
组件添加
- 菜单 Assets -> Import Package -> Characters 导入资源包,如下所示。也可以在商店页面中寻找Standard Assert内容,可免费添加所有的包,只需找到我们需要的人物模型包即可。
- 在层次视图,Context 菜单 -> 3D Object -> Plane 添加 Plane 对象
- 资源视图展开 Standard Assets :: Charactors :: ThirdPersonCharater :: Prefab
- 将 ThirdPersonController 预制拖放放入场景,改名为 Ethan
- 设置位置
- Plane 的 Transform 的 Position = (0,0,0)
- Ethan 的 Transform 的 Position = (0,0,0)
- Main Camera 的 Transform 的 Position = (0,1,-10)
- Plane 的 Transform 的 Position = (0,0,0)
- 运行,我们可以看到人物和地面、相机正确设置之后如下所示:
- 选择 Ethan 用上下文菜单 -> UI -> Canvas, 添加画布子对象
- 选择 Ethan 的 Canvas,用上下文菜单 -> UI -> Slider 添加滑条作为血条子对象
- 运行,我们可以看到一个比较大的滑动块
- 选择 Ethan 的 Canvas,在 Inspector 视图
- 设置 Canvas 组件 Render Mode 为 World Space
- 设置 Rect Transform 组件 (PosX,PosY,Width, Height) 为 (0,2,160,20)
- 设置 Rect Transform 组件 Scale (x,y) 为 (0.01,0.01)
- 设置 Canvas 组件 Render Mode 为 World Space
- 运行检查效果,此时 Slider 应该被调整到了Ethan的头部:
- 展开 Slider
- 选择 Handle Slider Area,禁灰(disable)该元素
- 选择 Background,禁灰(disable)该元素
- 选择 Fill Area 的 Fill,修改 Image 组件的 Color 为 红色
- 选择 Handle Slider Area,禁灰(disable)该元素
- 选择 Slider 的 Slider 组件
- 设置 MaxValue 为 100
- 设置 Value 为 75
- 设置 MaxValue 为 100
- 运行检查效果,发现血条可以随人物旋转
脚本添加
- 给 Canvas 添加以下脚本 LookAtCamera.cs,作用是使血条跟着人物的旋转,始终面对着屏幕:
using UnityEngine;
public class LookAtCamera : MonoBehaviour {
void Update () {
this.transform.LookAt (Camera.main.transform.position);
}
}
- 给Slider添加脚本,这个脚本添加了两个按钮,让我们可以随时改变其血条的多少。为了防止HP越界,当其小于0或者大于100时,我们不能再进行减少或增加。
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Health : MonoBehaviour
{
public Slider mainSlider;
public float HP;
private void Start()
{
mainSlider = GetComponent<Slider>();
HP = mainSlider.maxValue;
}
void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 100, 40), "Increase HP"))
HP += 10;
if (GUI.Button(new Rect(10, 70, 100, 40), "Decrease HP"))
HP -= 10;
if (HP > 100)
HP = 100;
if (HP < 0)
HP = 0;
mainSlider.value = HP;
}
}
为了更好的体现效果,我们将Slider的背景颜色打开,设成白色,这样模拟了游戏中空血条的样子。
效果展示
最终,我们的界面如下所示,有两个按钮以及一个人物,可以通过键盘上面的上下左右按键来控制移动,血条也会跟随人物的移动而移动:
当我们按下减少血量的按钮时,模拟人物受到了攻击,此时血量减少,白色部分是减少的血量,红色是剩余的血量:
预制体生成
要将血条设置成预制,我们只需要将Canvas对象拖入Perfabs文件夹,即可生成预制。
IMGUI实现
脚本设计
脚本主要还是生成了两个按钮和一个血条,能够通过按钮来控制血量的增减:
using UnityEngine;
public class BloodBar : MonoBehaviour
{
public float health = 0.0f;
private float resultHealth;
private Rect HealthBar;
void Start()
{
HealthBar = new Rect(200, 40, 200, 20);
resultHealth = health;
}
void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 100, 40), "Increase HP"))
resultHealth = resultHealth + 0.1f;
if (GUI.Button(new Rect(10, 70, 100, 40), "Decrease HP"))
resultHealth = resultHealth - 0.1f;
if (resultHealth > 1.0f)
resultHealth = 1.0f;
if (resultHealth < 0.0f)
resultHealth = 0.0f;
// make health bar change smoothly
health = Mathf.Lerp(health, resultHealth, 0.05f);
// show health
GUI.HorizontalScrollbar(HealthBar, 0.0f, health, 0.0f, 1.0f);
}
}
效果展示
制作好的血条效果如下所示,比起之前的UGUI,我们让血条的变化更加平滑:
预制体生成
要将血条设置成预制,我们只需要将这个空对象拖入Perfabs文件夹,即可生成预制。
对比与分析
IMGUI
IMGUI(Immediate Mode GUI)及时模式图形界面。它是代码驱动的 UI 系统,没有图形化设计界面,只能在 OnGUI 阶段用 GUI 系列的类绘制各种 UI 元素,因此 UI元素只能浮在游戏界面之上。
其优点在于:
- 符合游戏编程的传统
- 在修改模型,渲染模型这样的经典游戏循环编程模式中,在渲染阶段之后,绘制 UI 界面无可挑剔
- 这样的编程既避免了 UI 元素保持在屏幕最前端,又有最佳的执行效率,一切控制掌握在程序员手中
从血条的预制设计上来看,对比与UGUI,其实现非常简单,只需利用代码设计位置,然后将脚本拖拽到某个空对象上,整个界面就完成了。
但是我们也可以看出,这种编程模式的效果并没有UGUI好。UGUI的血条更加生动、形象、IMGUI显得比较落后,并且UGUI的血条能够随着人物的移动而移动,是游戏中常常实现的方式。
按照官方说法,其主要用于以下场景:
- 在游戏中创建调试显示工具
- 为脚本组件创建自定义的 Inspector 面板。
- 创建新的编辑器窗口和工具来扩展 Unity 环境
UGUI
Unity GUI / UGUI 是面向对象的 UI 系统。所有 UI 元素都是游戏对象,友好的图形化设计界面, 可在场景渲染阶段渲染这些 UI 元素。优点主要有:
- 所见即所得(WYSIWYG)设计工具,设计师也能参与程序开发
- 支持多模式、多摄像机渲染
- UI 元素与游戏场景融为一体的交互
- 面向对象的编程
在血条的预设中,虽然UGUI的设计步骤相比与IMGUI要更加的复杂化,但是其效果非常好,在设计过程中也体现了面向对象的设计方法。
上一篇: Unity3D中字体样式