Unity学习记录——UI设计

Unity学习记录——UI设计

前言

​ 本文是中山大学软件工程学院2020级3d游戏编程与设计的作业8

编程题:血条制作

1.相关资源

​ 本次项目之中的人物模型来自Starter Assets - Third Person Character Controller | 必备工具 | Unity Asset Store

​ 此处使用了以下路径的PlayerArmature预制,这个预制人物模型可以进行行走奔跑跳跃等动作,很适合血条的演示

请添加图片描述

​ 由于这个人物预制件之中挂载了一些实现动作的代码,其中实现了隐藏鼠标光标,会影响后续的演示,所以需要找到以下路径的代码,打开它

请添加图片描述

注释掉函数SetCursorState()中的代码,以方便后续血条UI之中点击按钮

private void SetCursorState(bool newState)
{
	// Cursor.lockState = newState ? CursorLockMode.Locked : CursorLockMode.None;
}

2.基本介绍

​ 以下介绍(中英双语)均来自unity官方手册,阐述了IMGUI与UGUI的大致内容。

​ 此处给出,目的是为了快速定位并了解本次课程以及作业的主要知识内容

(1)IMGUI

​ The “Immediate Mode” GUI system (also known as IMGUI) is an entirely separate feature to Unity’s main GameObject-based UI System. IMGUI is a code-driven GUI system, and is mainly intended as a tool for programmers. It is driven by calls to the OnGUI function on any script which implements it.

​ “即时模式”GUI 系统(也称为 IMGUI)是一个完全独立的功能系统,不同于 Unity 基于游戏对象的主 UI 系统。IMGUI 是一个代码驱动的 GUI 系统,主要用作程序员的工具。为了驱动该系统,需在实现脚本上调用 OnGUI 函数。

(2)UGUI

​ Unity UI is a set of tools for developing user interfaces for games and applications. It is a GameObject-based UI system that uses Components and the Game View to arrange, position, and style user interfaces.

​ Unity UI是一组用于开发游戏和应用程序用户界面的工具。它是一个基于GameObject的UI系统,可使用组件和 Game 视图来排列和定位用户界面并设置其样式

3.题目要求

血条 (Health Bar) 的预制设计。具体要求如下:

  • 分别使用 IMGUI 和 UGUI 实现
  • 使用 UGUI,血条是游戏对象的一个子元素,任何时候需要面对主摄像机
  • 分析两种实现的优缺点
  • 给出预制的使用方法

4.操作与代码详解

(1)IMGUI

​ 较为简单。血条为水平滚动条,通过按钮绑定加血扣血的函数,线性插值实现血条的平滑变化。

​ 部分API调用:

代码如下:

public class Blood_IMGUI : MonoBehaviour
{
    public float now = 10f;         //现在的血量
    private float target = 10f;     //将要达到的目标血量
    private Rect blood_area = new Rect(20, 20, 200, 50);        //血条所处位置
    private Rect up_area = new Rect(20, 50, 40, 20);            //加血按钮所处位置
    private Rect down_area = new Rect(180, 50, 40, 20);         //扣血按钮所处位置
    // 加血函数
    public void blood_up(float num)
    {
        target = target + num > 10f ? 10f : target + num;
    }
    //扣血函数
    public void blood_down(float num)
    {
        target = target - num < 0f ? 0f : target - num;
    }

    private void OnGUI()
    {
        if (GUI.Button(up_area, " + "))
            blood_up(1);
        if (GUI.Button(down_area, " - "))
            blood_down(1);
        // 线性插值
        now = Mathf.Lerp(now, target, 0.1f);
        // 创建水平滚动条,此处即血条
        GUI.HorizontalScrollbar(blood_area, 0f, now, 0f, 10f);
    }
}

​ 最终效果如下:

请添加图片描述

(2)UGUI
操作

在Scene之中右键新建一个Plane作为地面(这里我顺便做了平台的下四面围墙),再将之前所说的人物预制件PlayerArmature拖入其中

请添加图片描述

右键PlayerArmature,选择UI,Canvas,新建一个Canvas

请添加图片描述

​ 修改Canvas的部分属性

​ 重点:将Canvas的Render Mode改为World Space,其余属性即为调整Canvas的大小(Width,Height)以及缩放(Scale),旋转(Rotation)

请添加图片描述

​ 右键Canvas,选择UI,Slide,新建一个Slide

请添加图片描述

​ 此时可以看到血条的雏形,如下:

请添加图片描述

请添加图片描述

​ 为了进一步让血条成型,需要进行进一步的操作,如下:

  1. 禁用Handle Slide Area

请添加图片描述

​ 此时可以发现:血条上的圆球消失

请添加图片描述

  1. 修改其他部件(包括BackGround,Fill Area,Fill)的Rect Transform属性,同时将Fill中img控件的color修改为血条的颜色,此处我选择了红色

请添加图片描述

请添加图片描述

请添加图片描述

​ 此时拖动Slide的Value属性,就可以看到血条的平滑变化

请添加图片描述

​ 至此血条的制作基本完成,为了演示血条的变化,我再在CanVas上添加了两个button子类,来控制血条的增加减少

​ 添加button之后仍旧需要修改Rect Transform中对应的属性,如下

请添加图片描述

​ button中的文本可以通过button中的子对象text修改,此处改为 ‘+’ ‘-’ 号就可以

​ 最终效果如下图所示:

请添加图片描述

代码

​ 编写加血扣血的按钮事件代码,如下:

public class Blood_UGUI : MonoBehaviour
{
    private float now = 10f;        //现在的血量
    private float target = 10f;     //将要达到的目标血量
    public Slider blood;            //Slider,即血条
    GameObject up_button, down_button;  //控制加血扣血的两个按钮
    private void Start()
    {
        // 绑定按钮
        up_button = GameObject.Find("Button_up");
        Button a = up_button.GetComponent<Button>();
        down_button = GameObject.Find("Button_down");
        Button b = down_button.GetComponent<Button>();
        a.onClick.AddListener(delegate ()
        {
            this.OnClick(up_button);
        });
        b.onClick.AddListener(delegate ()
        {
            this.OnClick(down_button);
        });
    }
    // 按钮点击事件
    private void OnClick(GameObject sender)
    {
        if (sender.name == "Button_up")
            blood_up();
        if (sender.name == "Button_down")
            blood_down();
    }
    // 加血函数
    public void blood_up()
    {
        target = target - 1f < 0f ? 0f : target - 1f;
    }
    // 扣血函数
    public void blood_down()
    {
        target = target + 1f > 10f ? 10f : target + 1f;
    }

    void Update()
    {
        // 线性插值
        now = Mathf.Lerp(now, target, 0.1f);
        // 更新血量,此处为sliper的value
        blood.value = now;
        // 设置血条一直朝向摄像机
        transform.rotation = Quaternion.LookRotation(Vector3.forward);
    }
}

​ 最终得到的效果如下:

请添加图片描述

5.分析

​ 两种UI的优缺点分析:

IMGUI

​ IMGUI是一个基于事件的,代码驱动GUI系统。

​ 可知,IMGUI显然更加符合程序员的逻辑。即可以通过代码在页面上创建各种功能GUI,通过IMGUI,无需创建游戏对象,手动定位这些对象并编写一个处理对象功能的脚本,只需几行代码即可立即执行所有操作。对于程序员来说,这显然是非常灵活,易于使用的。

​ 同时在IMGUI之中,每一帧的UI都会被重新绘制。由此,当页面上的UI组件过多时,IMGUI的性能效率将会大打折扣,同时,IMGUI的调试工作也会更加困难。这也是unity官方不推荐将 IMGUI 用于游戏内运行时UI的原因。

​ 通过此特性,unity官方给出了IMGUI的用途如下:

即时模式 GUI 系统常用于:

  • 创建游戏内调试显示和工具。

  • 为脚本组件创建自定义检视面板。

  • 创建新的编辑器窗口和工具以扩展 Unity 本身。

from 即时模式 GUI (IMGUI) - Unity 手册

UGUI

​ UGUI是一个基于GameObject的UI系统。

​ 可知,UGUI通过使用Canvas来组织和渲染UI元素。由此,UGUI不仅仅可以使用层级结构来组织 UI 元素,并且可以使用多种布局方式来自动调整 UI 元素的位置和大小。所以,简单的开发方式和所见即所得的性质,使得UGUI成为更加易于没有编程的设计师入手的开发模式。

​ 同时,在面对创建复杂的UI时,UGUI的层级结构可能会变得过于复杂,难以维护。

演示

​ 演示视频已经上传至B站UI系统——血条_哔哩哔哩_bilibili

代码位置

​ 代码以及文档均已经上传至hw8· XiaoChen04_3/3D_Computer_Game_Programming - gitee

经上传至B站UI系统——血条_哔哩哔哩_bilibili

代码位置

​ 代码以及文档均已经上传至hw8· XiaoChen04_3/3D_Computer_Game_Programming - gitee

猜你喜欢

转载自blog.csdn.net/jmpei32534/article/details/128402802