第九次作业 UI系统——血条的预制设计

文章目录

  • 血条的预制设计
    • 1. IMGUI 实现
      • 1. 实现
      • 2. 效果展示
    • 2. UGUI实现
      • 1. 实现
      • 2. 效果展示
      • 3. 附加功能
    • 3. 优缺点对比
      • 1. IMGUI
      • 2. UGUI
    • 4. 使用方法

血条的预制设计

1. IMGUI 实现

1. 实现

主要是用HorizontalScrollbar(水平滚动条)的宽度作为血条的显示值来实现。
IMGUIHealthControl.cs

using System;
using UnityEngine;
using UnityEngine.UI;

public class IMGUIHealthControl : MonoBehaviour
{
     
    // 当前血量
    public float health = 0.0f;
    // 增/减后血量
    private float resulthealth;

    private Rect HealthBar;
    private Rect HealthUp;
    private Rect HealthDown;

    void Start()
    {
     
        //血条区域
        HealthBar = new Rect(250, 100, 200, 30);
        //加血按钮区域  
        HealthUp = new Rect(300, 140, 40, 20);
        //减血按钮区域
        HealthDown = new Rect(350, 140, 40, 20);
        resulthealth = health;
    }

    void OnGUI()
    {
     
        if (GUI.Button(HealthUp, "加血"))
        {
     
            resulthealth = resulthealth + 0.1f > 1.0f ? 1.0f : resulthealth + 0.1f;
        }
        if (GUI.Button(HealthDown, "减血"))
        {
     
            resulthealth = resulthealth - 0.1f < 0.0f ? 0.0f : resulthealth - 0.1f;
        }

        //插值计算health值,以实现血条值平滑变化
        health = Mathf.Lerp(health, resulthealth, 0.05f);

        // 用水平滚动条的宽度作为血条的显示值
        GUI.HorizontalScrollbar(HealthBar, 0.0f, health, 0.0f, 1.0f);
    }
}

接着,在 Hierarchy 视图中创建 Empty 对象,命名为IMGUI-HealthBar,然后将IMGUIHealthControl.cs挂载到IMGUI-HealthBar上。

2. 效果展示

IMGUI - health bar

2. UGUI实现

1. 实现

  1. 菜单 Assets -> Import Package -> Characters 导入资源。
  2. 在层次视图,Context 菜单 -> 3D Object -> Plane 添加 Plane 对象。
  3. 资源视图展开 Standard Assets -> Charactors -> ThirdPersonCharater -> Prefab。
  4. ThirdPersonController 预制拖放放入场景,改名为 Ethan
    第九次作业 UI系统——血条的预制设计_第1张图片
  5. 检查以下属性:
    Plane 的 Transform 的 Position = (0,0,0)
    Ethan 的 Transform 的 Position = (0,0,0)
    Main Camera 的 Transform 的 Position = (0,1,-10)
  6. 运行检查效果。
    运行时,可能会报编译错误,打开console, 有如下错误信息:
    在这里插入图片描述
    意思是调用了已被弃用的GUIText。
    解决办法:打开该文件,修改以下两处。
    第九次作业 UI系统——血条的预制设计_第2张图片
    然后重新运行就可以了。
  7. 选择 Ethan 用上下文菜单 -> UI -> Canvas, 添加画布子对象。
  8. 选择 Ethan 的 Canvas,用上下文菜单 -> UI -> Slider 添加滑条作为血条子对象。
  9. 运行检查效果。
  10. 选择 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)
  11. 运行检查效果,应该是头顶 Slider 的 Ethan,用键盘移动 Ethan,观察。
  12. 展开 Slider
    (1) 选择 Handle Slider Area,禁灰(disable)该元素
    如图所示,就是把箭头所指框的勾去掉。
    第九次作业 UI系统——血条的预制设计_第3张图片
    (2) 选择 Background,禁灰(disable)该元素
    (3) 选择 Fill Area 的 Fill,修改 Image 组件的 Color 为 红色
  13. 选择 Slider 的 Slider 组件:
    (1) 设置 MaxValue 为 100
    (2) 设置 Value 为 75
  14. 运行检查效果,发现血条随人物旋转。
  15. 给 Canvas 添加以下脚本 LookAtCamera.cs:
using UnityEngine;

public class LookAtCamera : MonoBehaviour {
     

	void Update () {
     
		this.transform.LookAt (Camera.main.transform.position);
	}
}

2. 效果展示

UGUI - health Bar

3. 附加功能

假如想让Ethan运动的时候,有回血和减血的变化,可以写一个脚本,控制血条的变化。
HealthControl.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class HealthControl : MonoBehaviour
{
     
    // 血条
    public Slider EthanSlider;
    // 恢复血的时间的间隔
    public float duration = 10;
    // 用于计时
    private float dur_time = 0;
    // 当前血量
    private float health;
    // 增/减后血量
    private float resultHealth;
    // 增减血
    private bool flag = false;
    // Start is called before the first frame update
    void Start()
    {
     
        // 设置最大血量、最小血量、回血间隔以及现在血量
        EthanSlider.maxValue = 100;
        EthanSlider.minValue = 0;
        duration = 10;
        // EthanSlider.wholeNumbers = true;
        EthanSlider.value = EthanSlider.maxValue / 2;
        health = EthanSlider.value;
        resultHealth = health;
    }

    // Update is called once per frame
    void Update()
    {
     
        // 计时以回血
        if (EthanSlider.value < EthanSlider.maxValue - 0.1 && !flag)
        {
     
            dur_time += Time.deltaTime;
            if (dur_time >= duration)
            {
     
                resultHealth = EthanSlider.value + 10 > EthanSlider.maxValue ? EthanSlider.maxValue : EthanSlider.value + 10;
                dur_time = 0;
            }
        }
        // 发生碰撞,减血
        else if (flag)
        {
     
            resultHealth = EthanSlider.value - 20 < EthanSlider.minValue ? EthanSlider.minValue : EthanSlider.value - 20;
            flag = false;
        }
        // 平滑减少血量
        health = Mathf.Lerp(health, resultHealth, 0.05f);
        EthanSlider.value = health;
        // 控制slider中Fill Area的显示,以更符合血量的显示
        if (EthanSlider.value <= 0.01)
            EthanSlider.transform.GetChild(1).localScale = Vector3.zero;
        else
            EthanSlider.transform.GetChild(1).localScale = Vector3.one;
    }
    public void ReduceHealth()
    {
     
        flag = true;
    }
}

然后将该脚本挂载到 Ethan 上,EthanSlider 选择 Slider (血条)。
第九次作业 UI系统——血条的预制设计_第4张图片

3. 优缺点对比

1. IMGUI

优点

IMGUI(Immediate Mode GUI):及时模式图形界面。它是代码驱动的 UI 系统,没有图形化设计界面,在 OnGUI 阶段用 GUI 系列的类绘制各种 UI 元素, UI元素只能浮在游戏界面之上。这样的编程即避免了 UI 元素保持在屏幕最前端,又有最佳的执行效率,一切控制掌握在程序员手中,这对早期计算和存储资源贫乏的游戏设备来说,更是弥足珍贵。IMGUI 的存在符合游戏编程的传统,即使在今天它依然没有被官方宣判为遗留(将要淘汰的)系统。

缺点

  1. 由于是代码驱动的,对开发人员的编程能力有一定要求,开发效率低下,并不十分友好。
  2. 当设计玩家可能使用并与之交互的普通游戏内用户界面时,不如 IGUI 。
  3. 对于复杂的界面,通过编程设计界面将会十分耗费时间,且难以更改和调试。

应用

IMGUI主要应用于以下场景:

  1. 在游戏中创建调试显示工具
  2. 为脚本组件常见自定义的Inspector面板
  3. 创建新的编辑器窗口和工具来扩展Unity环境。

2. UGUI

优点

UI :(User Interface):用户界面。Unity GUI / UGUI 是面向对象的 UI 系统。所有 UI 元素都是游戏对象,友好的图形化设计界面, 可在场景渲染阶段渲染这些 UI 元素。UGUI 是面向对象的系统,能够支持多模式、多摄像机渲染,使用所见即所得设计工具,设计师不需要程序员的帮助就能直接创造游戏元素乃至游戏程序。

缺点

  1. UGUI 没有 UIWrap 来循环 scrollview 内容。
  2. UGUI 暂时没有Tween组件。

4. 使用方法

  1. 在Assets中创建Resources文件夹,然后在Resources中创建Prefabs文件夹。
  2. 将 IMGUI 中创建的 IMGUI-HealthBar 和 UGUI 中创建Canvas(重新命名为UGUI-HealthBar) 拖拽到Prefabs中。
  3. 使用时,用 Resources.Load 函数加载即可。

你可能感兴趣的:(3D游戏编程,unity,游戏)