3DGame-unity-HW9
18342063 刘智斌
作业要求
血条(Health Bar)的预制设计。具体要求如下
- 分别使用 IMGUI 和 UGUI 实现
- 使用 UGUI,血条是游戏对象的一个子元素,任何时候需要面对主摄像机
- 分析两种实现的优缺点
- 给出预制的使用方法
项目设计大纲
- IMGUI:在游戏界面的右上角显示一个血条控制器,可以通过按钮调整数指。
- UGUI:将一个血条预设作为游戏角色的子对象,跟随游戏角色移动,其数值可以随IMGUI血条改变而改变。
具体实现
IMGUI血条
血条的形态与水平滚动条类似,于是可以利用HorizontalScrollbar对象来实现血条的显示和变化。
GUI.HorizontalScrollbar(healthBar, 0.0f, health, 0.0f, 1.0f);
其中第三个参数是水平滚动条的大小,用生命值health的数值来表示水平滚动条的大小即可达到血条的变化效果。
第一个参数是水平滚动条的位置,其类型是一个Rect,为了使其出现在游戏画面的右上方,进行以下声明:
healthBar = new Rect(Screen.width - 220, 20, 200, 50);
同时需要两个按钮来实现血量的增加和减少,可以设置对应的Button对象,点击则改变血量,但是直接改变血量会让水平滚动条的变化不平滑,于是引入了函数:Mathf.Lerp,计算目标血量和当前血量的插差值,按照步长逐步减少。
if (GUI.Button(healthUp, "live up"))
{
curHealth = curHealth + 0.1f > 1.0f ? 1.0f : curHealth + 0.1f;
}
if (GUI.Button(healthDown, "live down"))
{
curHealth = curHealth - 0.1f < 0.0f ? 0.0f : curHealth - 0.1f;
}
health = Mathf.Lerp(health, curHealth, 0.05f);
综上,IMGUI血条实现的代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthBarIMGUI : MonoBehaviour
{
public float health = 0.0f;
private float curHealth;
private Rect healthBar;
private Rect healthUp;
private Rect healthDown;
public Slider healthSlider;
void Start()
{
healthBar = new Rect(Screen.width - 220, 20, 200, 50);
healthUp = new Rect(Screen.width - 220, 50, 70, 40);
healthDown = new Rect(Screen.width - 90, 50, 70, 40);
curHealth = health;
}
void OnGUI()
{
if (GUI.Button(healthUp, "live up"))
{
curHealth = curHealth + 0.1f > 1.0f ? 1.0f : curHealth + 0.1f;
}
if (GUI.Button(healthDown, "live down"))
{
curHealth = curHealth - 0.1f < 0.0f ? 0.0f : curHealth - 0.1f;
}
health = Mathf.Lerp(health, curHealth, 0.05f);
GUI.HorizontalScrollbar(healthBar, 0.0f, health, 0.0f, 1.0f);
healthSlider.value = health;
}
}
UGUI血条
UGUI血条要求血条是游戏角色的子对象,因此我们从Standard Assets资源包中采用一个游戏角色,其不仅可以承载血条,同时可以通过键盘操作其行动。在资源包中,其是名为ThirdPersonCharacter的预设,我将其名为Chris。
然后需要设计血条预设。首先在Chris的对象树下创建一个Canvas对象,将其改名为HealthBar,再在HealBar下创建一个Slide对象,如下图:
然后我们需要调整HealthBar的大小和位置,具体设置如下:HealthBar的Render Mode设为World Space,Rect Transform 组件的位置改为(0,2,0),大小改为(0.01,0.01,0),如下图。
禁用Slider对象的Background和Handle Slide Area子对象,然后对Fill Area的子对象Fill进行设置。将其Image插件的Color项改为绿色,则可以显示绿色血条。
另外,如果到此为止,血条的朝向会随着角色的朝向改变,玩家无法随时看到血条数值,因此需要将血条始终朝向摄像头,本项目中摄像头位于Forward位置,因此只需要下面一行代码:
this.transform.rotation = Quaternion.LookRotation(Vector3.forward);
别忘了,UGUI的血条会随着IMGUI的变化而变化,所以需要建立healthbar和IMGUI血条脚本的联系。在IMGUI血条脚本中加入一个公开的Slide对象,并将HealthBar挂载上去,在脚本中同步血量的变化。
public Slider healthSlider;
healthSlider.value = health;
优缺点分析
IMGUI
- 优点:
- 使用方便,上手容易。
- 没有状态,维护方便。
- UI元素在屏幕最前端,提高执行效率。
- 缺点:
- 效率低下,每次都需要重新生成所有组件
- 没有状态,配置不够灵活,实现运动、动画等比较麻烦
UGUI
- 优点:
- 支持多模式、多摄像机渲染。
- 每次生命周期不需要重复遍历一次UI组件,效率较高。
- 缺点:
- 使用比较繁琐、对不同的功能需要提供不同的canvas,并单独配置。