CUFMH2Blog

3D Game 9 - UI 系统

Word count: 1.4k Reading time: 6 min
2019-11-20 calculating Share

横看成岭侧成峰,远近高低各不同。不识庐山真面目,只缘身在此山中。

— 【宋】苏轼 《题西林壁》

UI 系统

Unity UI 技术概述

UI 即 User Interface(用户界面)的简称。在许多软件中,采用狭义的概念,特指窗体、面板、按钮、文本框等人们熟悉的人机交互元素,及其组织与风格(也称皮肤)。Unity UI 系统采用上述狭义概念。

Unity 目前支持三套完全不同风格的 UI 系统:

  • 4.0 及以前 - IMGUI(Immediate Mode GUI)及时模式图形界面。它是代码驱动的 UI 系统,没有图形化设计界面,只能在 OnGUI 阶段用 GUI 系列的类绘制各种 UI 元素,因此 UI元素只能浮在游戏界面之上。
  • 5.0 及以后 - Unity GUI / UGUI 是面向对象的 UI 系统。所有 UI 元素都是游戏对象,友好的图形化设计界面, 可在场景渲染阶段渲染这些 UI 元素。
  • 2018.3 及以后 - UXML(unity 扩展标记语言)。基于 IMGUI 的 AXML 包装,方便移动应用开发者入门。

UGUI 基础

画布

画布(Cavas)是绘图区域, 同时是 ui 元素的容器。 容器中 ui 元素及其子 UI 元素都将绘制在其上。 拥有Canvas组件的游戏对象都有一个画布,它空间中的子对象,如果是 UI 元素将渲染在画布上。画布区域在场景视图中显示为矩形。这使得定位UI元素变得非常容易,无需随时显示游戏运行视图。

UI 布局基础

每个UI元素都被表示为一个矩形,为了相对于 Canvas 和 其他 UI 元素实现定位,Unity 在 Transform 基础上定义了 RectTransform (矩形变换) 支持矩形元素在 2/3D 场景中变换。

UI 组件与元素

UI 部件都是用 Script 开发的自定义组件。包括在 UI、Layout 和 Rendering 等分类。

圆形遮罩、动画、富文本、血条

圆形遮罩、动画、富文本、血条等都是菜单制作,初步理解 Text,Image,RowImage,Mask 等的基本使用技巧。

作业与练习:UI 效果制作

作业要求

进入 NGUI 官方网站,使用 UGUI 实现“Inventory 背包系统”的效果。

预期目标

  1. 实现背包系统的右侧,即背包栏,一共3*3个格子,可以存放物品;
  2. 实现背包系统的中侧,即用一个物体来表示玩家主体;
  3. 实现背包系统的左侧,即佩戴栏,一共1*3个格子,可以佩戴物品;
  4. 实现物品的显示,本设计中用图片代替;
  5. 实现背包系统界面随鼠标移动而旋转的效果;
  6. 实现物体的佩戴、摆放、替换过程。

完成情况

游戏界面1

游戏界面2

游戏界面3

项目设计

目录结构

完成步骤

  • 结构设计:使用背景板来构建背包系统的背景;将摄像机作为母对象,并添加EventSystem;使用普通的GameObject来表示玩家主体;使用Canvas来设置BackpackSystem;使用Grid LayOut Group部件来对背包栏和佩戴栏进行布局;用空的Image对象来表示空格子及物品。

  • 代码设计1:对Inventory对象添加脚本以实现随鼠标移动而旋转的效果,只需要获取界面鼠标的位置,并随之改变角度即可,代码如下所示。

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;

    public class Mouse : MonoBehaviour
    {
    Transform trans;
    Quaternion quaternion;
    public Vector2 lerp = Vector2.zero;
    public Vector2 v2 = new Vector2(4f, 2f);

    void Start()
    {
    trans = transform;
    quaternion = trans.localRotation;
    }

    void Update()
    {
    Vector3 pos = Input.mousePosition;
    float mywidth = Screen.width * 0.5f;
    float myheight = Screen.height * 0.5f;
    float x = Mathf.Clamp((pos.x - mywidth) / mywidth, -0.5f, 0.5f);
    float y = Mathf.Clamp((pos.y - myheight) / myheight, -0.5f, 0.5f);
    lerp = Vector2.Lerp(lerp, new Vector2(x, y), Time.deltaTime * 2f);
    trans.localRotation = quaternion * Quaternion.Euler(-lerp.y * v2.y, -lerp.x * v2.x, 0f);
    }
    }
  • 代码设计2:对表示物体的Image对象添加脚本以实现拖拽的UI效果,需要使用到接口IBeginDragHandler、IDragHandler、IEndDragHandler,代码如下所示。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.EventSystems;
    using System.Collections;
    using System.Collections.Generic;

    public class Drag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
    {
    Transform trans;
    RectTransform rect_trans;
    CanvasGroup canvas_group;
    GameObject grid = null;
    Color grid_color_1;
    Color grid_color_2 = Color.grey;
    public Vector3 v3;

    void Start()
    {
    // Debug.Log("000");
    trans = this.transform;
    v3 = trans.position;
    rect_trans = this.transform as RectTransform;
    canvas_group = GetComponent<CanvasGroup>();
    }

    void Update()
    {
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
    // Debug.Log("OnBeginDrag");
    canvas_group.blocksRaycasts = false;
    grid = eventData.pointerEnter;
    grid_color_1 = grid.GetComponent<Image>().color;
    v3 = trans.position;
    gameObject.transform.SetAsLastSibling();
    }

    public void OnDrag(PointerEventData eventData)
    {
    // Debug.Log("OnDrag");
    bool flag = true;
    Vector3 mouse_position;
    if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rect_trans, eventData.position, eventData.pressEventCamera, out mouse_position))
    {
    rect_trans.position = mouse_position;
    }
    GameObject now_grid_p = eventData.pointerEnter;
    if (now_grid_p == null)
    {
    flag = false;
    }
    else if (now_grid_p.name != "bag_grid")
    {
    flag = false;
    }
    if (flag)
    {
    Image pic = now_grid_p.GetComponent<Image>();
    grid.GetComponent<Image>().color = grid_color_1;
    if (grid != now_grid_p)
    {
    grid.GetComponent<Image>().color = grid_color_1;
    grid = now_grid_p;
    }
    pic.color = grid_color_2;
    }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
    // Debug.Log("OnEndDrag");
    GameObject now_grid_p = eventData.pointerEnter;
    if (now_grid_p == null)
    {
    trans.position = v3;
    }
    else
    {
    if (now_grid_p.name == "bag_grid")
    {
    trans.position = now_grid_p.transform.position;
    v3 = trans.position;
    now_grid_p.GetComponent<Image>().color = grid_color_1;
    }
    else
    {
    if (now_grid_p.name == eventData.pointerDrag.name && now_grid_p != eventData.pointerDrag)
    {
    Vector3 target_pos = now_grid_p.transform.position;
    now_grid_p.transform.position = v3;
    trans.position = target_pos;
    v3 = trans.position;
    }
    else
    {
    trans.position = v3;
    }
    }
    }
    grid.GetComponent<Image>().color = grid_color_1;
    canvas_group.blocksRaycasts = true;
    }
    }

项目地址

代码地址:https://github.com/CUFMHeart/3D-Game-Programming-Design/tree/master/homework9/

视频地址:https://www.bilibili.com/video/av76655299/

参考资料

[1] UI系统_教学讲义

[2] Maunal

[3] https://docs.unity3d.com/Manual/UISystem.html

CATALOG
  1. 1. UI 系统
    1. 1.1. Unity UI 技术概述
    2. 1.2. UGUI 基础
  2. 2. 作业与练习:UI 效果制作
    1. 2.1. 作业要求
    2. 2.2. 预期目标
    3. 2.3. 完成情况
    4. 2.4. 项目设计
      1. 2.4.1. 项目地址
  3. 3. 参考资料