一.作业要求
血条(Health Bar)的预制设计。具体要求如下
- 分别使用 IMGUI 和 UGUI 实现
- 使用 UGUI,血条是游戏对象的一个子元素,任何时候需要面对主摄像机
- 分析两种实现的优缺点
- 给出预制的使用方法
二.实现过程
IMGUI实现
在IMGUI中可以使用HorizontalScrollbar(水平滚动条)的宽度作为血条的显示值。
具体代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class IMGUI : MonoBehaviour {
public float health;
private float res;
public Slider healthSlider;
void Start(){
health = 1.0f;
res = 1.0f;
}
void OnGUI(){
if (GUI.Button (new Rect(250, 20, 40, 20), "+")) {
if (res + 0.2f > 1.0f) res = 1.0f;
else res = res + 0.2f;
}
if (GUI.Button (new Rect(250, 50, 40, 20), "-")) {
if (res - 0.2f < 0.0f) res = 0.0f;
else res = res - 0.2f;
}
health = Mathf.Lerp(health, res, 0.05f);
GUI.color = Color.red;
GUI.HorizontalScrollbar(new Rect(20, 20, 200, 20), 0.0f, health, 0.0f, 1.0f);
healthSlider.value = health*100;
}
}
建立空的游戏对象,然后将该脚本挂载在空的游戏对象之下就可以显示血条了。
中间值res的加入是为了通过lerp函数让血条平缓变化,而不对突然变化。Mathf.Lerp是插值的作用。
这样就实现了通过IMGUI制作血条。
UGUI实现
- 菜单 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
- 选择 Handle Slider Area,禁灰(disable)该元素
- 选择 Background,禁灰(disable)该元素
- 选择 Fill Area 的 Fill,修改 Image 组件的 Color 为 红色
- 选择 Slider 的 Slider 组件
- 设置 MaxValue 为 100
- 设置 Value 为 75
这时运行会发现血条随人物旋转。
所以我们需要给 Canvas 添加脚本使得血条一直面向主摄像机
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAtCamera : MonoBehaviour {
void Update () {
this.transform.LookAt (Camera.main.transform.position);
}
}
这样就完成了UGUI血条制作。
接下来实现IMGUI的血条和UGUI的血条一起加减。
在IMGUI脚本中新增变量Slider healthSlider,并进行控制
然后将convas中的slider挂载到脚本上就可以控制两个血条了。
最后将Canvas对象拖入Perfabs文件夹,就生成了预制体。
三.分析两种实现的优缺点
IMGUI(Immediate Mode GUI)及时模式图形界面。它是代码驱动的 UI 系统,没有图形化设计界面,只能在 OnGUI 阶段用 GUI 系列的类绘制各种 UI 元素,因此 UI元素只能浮在游戏界面之上。IMGUI 的存在符合游戏编程的传统,即使在今天它依然没有被官方宣判为遗留(将要淘汰的)系统(Legacy Systems)。在修改模型,渲染模型这样的经典游戏循环编程模式中,在渲染阶段之后,绘制 UI 界面无可挑剔(参考Execution Order of Event Functions)。这样的编程即避免了 UI 元素保持在屏幕最前端,又有最佳的执行效率,一切控制掌握在程序员手中,这对早期计算和存储资源贫乏的游戏设备来说,更是弥足珍贵。当然,早年 UI 交互手段就是绘制图片和文本,检测输入事件等基本任务。按 Unity 官方说法,IMGUI 主要用于以下场景:
- 在游戏中创建调试显示工具
- 为脚本组件创建自定义的 Inspector 面板。
- 创建新的编辑器窗口和工具来扩展 Unity 环境。
所以IMGUI的优点:
- IMGUI 的存在符合游戏编程的传统
- 在修改模型,渲染模型这样的经典游戏循环编程模式中,在渲染阶段之后,绘制 UI 界面无可挑剔
- 这样的编程既避免了 UI 元素保持在屏幕最前端,又有最佳的执行效率,一切控制掌握在程序员手中
缺点:
- 传统代码驱动的 UI 面临效率低下
- 难以调试等
Unity GUI / UGUI 是面向对象的 UI 系统。所有 UI 元素都是游戏对象,友好的图形化设计界面, 可在场景渲染阶段渲染这些 UI 元素。
UGUI 的优势:
- 所见即所得(WYSIWYG)设计工具
- 支持多模式、多摄像机渲染
- 面向对象的编程
缺点:
- UGUI如果人物过多,需要太多的canvas
四.预制的使用方法
- 直接将IMGUItest预制体拖入场景
- 按照上述方法导入资源,用预制体生成游戏对象Ethan,构建基本场景
- 将Canvas预制体拖入到Ethan对象,成为其子对象
- 将Canvas的子对象Slider拖入IMGUI.cs中的HealthSlider属性,使其实现拖动。
五.实验心得与总结
这次作业中通过两种方式实现了血条的制作,我对UI的使用以及预制体的使用方法有了更深的了解,也对现在Unity 三套不同风格的 UI 系统有了基本的认识,对于其中的优缺点做了比较。