3D游戏编程的第九次作业:
- 血条(Health Bar)的预制设计
要求
- 分别使用 IMGUI 和 UGUI 实现
- 使用 UGUI,血条是游戏对象的一个子元素,任何时候需要面对主摄像机
- 分析两种实现的优缺点
- 给出预制的使用方法
实现过程
IMGUI
IMGUI主要通过HorizontalScrollbar
实现,将其宽度作为血条的显示值。
具体代码如下,主要就是创建了一个矩形的HorizontalScrollbar
作为血条,以及两个按钮,使得我们对于血量可以进行直观的增减,按钮触发的事件直接改变血量。
其中,参考以前师兄们的博客,使用了线性插值函数Lerp()
,该函数有很多用法,这里的Mathf.Lerp(from : float, to : float, t : float)
函数基于浮点数t
返回a
到b
之间的插值,t
限制在0~1之间。当t
= 0返回from,当t
= 1 返回to。当t
= 0.5 返回from和to的平均值。 因此,通过这个函数可以实现血量的平滑改变。
1 | public class IMGUI : MonoBehaviour |
UGUI
通过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 添加以下脚本使其一直朝着相机方向。
1 | public class LookAtCamera : MonoBehaviour { |
到此,基础的血条就完成了,但为了显示其血量的变化,我在游戏场景增加了一个障碍物,并使得人物在撞到障碍物后血量会下降。
障碍物通过Cube实现,添加如下脚本:
1 | private void OnCollisionEnter(Collision collision) |
同时,给人物Ethan的子对象Canvas添加如下控制器代码,扣血的原理和IMGUI的原理相同,当Cube检测到碰撞后使得flag变量变为true,通过控制Slider的值实现血量的改变。
1 | public class Controller : MonoBehaviour |
实现效果
IMGUI
UGUI
优缺点分析
IMGUI
个人认为IMGUI比较符合传统的UI写法,即通过代码的方式生成一个UI对象,并且定义与该对象进行交互时会发生的事件,这和我这个学期正在学习的IOS开发比较类似,这样的编程使得一切都在程序员的掌控之中,对于程序员来说应该是十分友好的。但缺点就是一切都是由代码生成,那么当需要的UI界面十分复杂时,就需要大量的代码支持,此时效率就会比较低下,调试起来也很困难,同时对于非程序员来说使用就比较困难,例如设计师们。
UGUI
UGUI的出现就是为了解决IMGUI对于设计师们不够友好的困境,无需编码,而只需要创建UI组件并设置相应属性即可。这种所见即所得的设计方式让设计师们也能够参与程序的开发,脱离程序员的帮助。而其缺点,目前我使用的还比较简单,暂时还不太清楚有何缺点,可能对于作为程序员的我来说,创建的方式相对比较复杂,有很多属性的设置需要查看相应的文档才能清楚,不像程序中的方法调用那样直观。
预制的使用方法
本项目中有IMGUI
和UGUI
两个预制,分别对应了各自的血条实现。使用方法如下:
当需要使用由
IMGUI
实现的血条时,只需要直接将该预制拖入场景即可。当需要使用由
UGUI
实现的血条时,首先按照上文所说的搭建好基本场景,例如导入人物资源、设置 Plane 对象。然后将UGUI
预制拖入到 Ethan对象下,成为其子对象,然后将UGUI
预制对象下的 子对象Slider拖入对象的Controller.cs组件中的MainSlider属性即可。如需实现碰撞效果,需要再创建一个Cube对象,并为其添加脚本中的Collider.cs。