作业内容
血条(Health Bar)的预制设计。具体要求如下:
- 分别使用 IMGUI 和 UGUI 实现
- 使用 UGUI,血条是游戏对象的一个子元素,任何时候需要面对主摄像机
- 分析两种实现的优缺点
- 给出预制的使用方法
实现
UGUI
UGUI的实现可以参考老师教程中的操作 09-05,health bar 练习。
- 菜单 Assets -> Import Package -> Characters 导入资源
- 在层次视图,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) - 运行检查效果
- 选择 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) - 运行检查效果,应该是头顶 Slider 的 Ethan,用键盘移动 Ethan,观察
- 展开 Slider
选择 Handle Slider Area,禁灰(disable)该元素
选择 Background,禁灰(disable)该元素
选择 Fill Area 的 Fill,修改 Image 组件的 Color 为 红色 - 选择 Slider 的 Slider 组件
设置 MaxValue 为 100
设置 Value 为 75 - 运行检查效果,发现血条随人物旋转
- 给 Canvas 添加以下脚本 LookAtCamera.cs
using UnityEngine;
public class LookAtCamera : MonoBehaviour {
void Update () {
this.transform.LookAt (Camera.main.transform.position);
}
}
最终效果:
IMGUI
与IGUI类似,先将第三人称的人和Plane设置好位置,然后新建一个empty对象作为第三人称Ethan的子对象。
然后编写脚本HealthBar.cs用于控制血条。
脚本有如下成员:
resulthealth用于记录hp值;father用于记录父对象(也就是Ethan)的Transform,主要用于实现血条跟随人物行走;后面三个框是组成血条的部分。
实现血条跟随任务行走的代码如下:
HealthBar = new Rect(Screen.width / 2 + father.position.x * father.localScale.x * 30 - father.localScale.x * 50,
Screen.height / 2 + (father.position.z - father.localScale.y * 7) * father.localScale.z * 10,
father.localScale.x * 100, father.localScale.z * 10);
Add = new Rect(Screen.width / 2 + father.position.x * father.localScale.x * 30 + father.localScale.x * 55,
Screen.height / 2 + (father.position.z - father.localScale.y * 7) * father.localScale.z * 9.5f,
father.localScale.x * 20, father.localScale.z * 10);
Minus = new Rect(Screen.width / 2 + father.position.x * father.localScale.x * 30 - father.localScale.x * 75,
Screen.height / 2 + (father.position.z - father.localScale.y * 7) * father.localScale.z * 9.5f,
father.localScale.x * 20, father.localScale.z * 10);
实现了血条大致位于人物上方,而且还有近大远小的效果。
加减血量的代码:
if (GUI.Button(Add, "+")){
resulthealth = resulthealth + 0.1f > 1.0f ? 1.0f : resulthealth + 0.1f;
}
if (GUI.Button(Minus, "-")){
resulthealth = resulthealth - 0.1f < 0.0f ? 0.0f : resulthealth - 0.1f;
}
如果超过了1,则设为1。
最后是血条变化的代码,使用了Mathf.Lerp插值计算血量,从而使血量能够平滑增加/减少。
health = Mathf.Lerp(health, resulthealth, 0.05f);
GUI.HorizontalScrollbar(HealthBar, 0, health, 0.0f, 1.0f);
最终效果:
对比
IMGUI
优点:
- 编程实现,符合游戏编程的传统;
- 直接渲染在屏幕前端;
- 对新手友好,入门容易,同时帮助理解游戏引擎渲染的调用函数;
缺点:
- 无法直观看到UI布局情况,更改位置需要慢慢调试;
- 只能渲染在屏幕最前端,无法在游戏场景中使用。
UGUI
优点:
- 符合游戏编程传统;
- 支持多模式、多摄像机渲染;
- UI 元素与游戏场景融为一体的交互;
缺点:
- 难以调试;
- 性能较差,效率较低;
预置使用方法
- 直接打开保存好的场景:
- UGUI只需要直接将预置Ethan拖出放到合适的位置;IMGUI则要先拖出空的第三人称对象,并新建一个空子对象,然后将脚本挂在子对象上。