UGUI中的Image和RawImage的区别

Image 组件

Image 组件是UGUI中最常用的用于显示图像的组件。它支持多种图像类型(如Sprite、Sprite Atlas、Texture2D等),并且提供了一些方便的属性来调整图像的显示方式,如**color(颜色)、material(材质)、sprite**(精灵)等。

主要特点:
  1. 支持Sprite和Texture2D:可以直接使用Unity中的Sprite或Texture2D资源。
  2. 具有内置的颜色调整:可以通过**color**属性调整图像的颜色。
  3. 支持材质:可以通过**material**属性应用自定义的Shader效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using UnityEngine;
using UnityEngine.UI;

public class ImageExample : MonoBehaviour
{
public Image myImage; // 拖拽赋值或通过代码查找

void Start()
{
// 设置Sprite(需要先在项目中有一个Sprite资源)
myImage.sprite = Resources.Load<Sprite>("MySprite");

// 设置颜色
myImage.color = Color.red;
}
}

RawImage 组件

RawImage 组件则提供了更底层的图像显示功能。它主要用于显示Texture2D类型的图像,并且不提供像Image那样的高级特性(如颜色调整或Sprite支持)。但是,RawImage具有更高的灵活性,因为它允许你直接使用原始的Texture2D数据。

主要特点:
  1. 仅支持Texture2D:只能使用Texture2D资源。
  2. 无内置颜色调整:颜色调整需要在Shader级别进行(如果需要的话)。
  3. 更高的灵活性:可以直接操作Texture2D数据,实现更复杂的图像效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
using UnityEngine.UI;

public class RawImageExample : MonoBehaviour
{
public RawImage myRawImage; // 拖拽赋值或通过代码查找

void Start()
{
// 假设你有一个Texture2D资源(需要先在项目中创建或加载)
Texture2D myTexture = new Texture2D(128, 128);
// ... 这里可以填充myTexture的数据 ...

// 设置Texture2D到RawImage
myRawImage.texture = myTexture;

// 注意:RawImage没有color属性,所以颜色调整需要在Shader中进行
}
}

Canvas的 Render Mode(渲染模式) 三种方式

渲染模式 中文名 作用 例子
Screen Space - Overlay 屏幕空间-覆盖层 此模式下,Canvas始终渲染在屏幕的最上层,不受任何相机(Camera)的影响。Canvas的坐标基于屏幕像素,左上角为(0,0),右下角为(Screen.width, Screen.height) 显示一个始终位于屏幕中心的UI元素(如文本)。
Screen Space - Camera 屏幕空间-相机 此模式下,Canvas会渲染到指定的相机上。Canvas的坐标仍然基于屏幕像素,但会受到相机的影响(如相机的裁剪平面、视场角等)。 在一个自定义相机视图中显示UI元素。
World Space 世界空间 此模式下,Canvas被视为场景中的一个普通对象,具有三维坐标和旋转。Canvas会渲染到所有能看到它的相机上。 将一个UI面板放置在三维场景中的某个位置,并随着玩家移动。

Canvas怎么适配屏幕

UI缩放模式

Property Function
UI Scale Mode Canvas中UI元素的缩放模式
Constant Pixel Size 使UI保持自己的尺寸,与屏幕尺寸无关。
Scale With Screen Size 屏幕尺寸越大,UI越大。
Constant Physical Size 使UI元素保持相同的物理大小,与屏幕尺寸无关。
Constant Pixel Size 和 Constant Physical Size 的区别 两者本质相同,但 Constant Pixel Size 通过逻辑像素大小调节来维持缩放,而 Constant Physical Size 通过物理大小调节来维持缩放。

如何在不同分辨率下保持UI的一致性

  • 多屏分辨率下的UI布局一般考虑两个问题:

    • 布局元素的位置,即屏幕分辨率变化的情况下,布局元素的位置可能固定不动,导致布局元素可能超出边界;

    • 布局元素的尺寸,即在屏幕分辨率变化的情况下,布局元素的大小尺寸可能会固定不变,导致布局元素之间出现重叠等功能。

    • 为了解决这两个问题,在Unity UGUI体系中有两个组件可以来解决问题,分别是布局元素的Rect Transform和Canvas的Canvas Scaler组件。

CanvasScaler中UI Scale Mode有三种模式,Constant Pixel Size、Scale With Screen Size、Constant Physical Size,其中第二个就是根据屏幕分辨率来进行缩放适配。在这个模式下,有两个参数,一个是我们在开发过程中的标准分辨率,一个是屏幕的匹配模式,通过这里面的设置,就可以完成多分辨率下的适配问题。

UGUI是射线检测的还是单纯的计算坐标?

当用户点击屏幕时, uGUI会首先确定点击的屏幕坐标。然后,它会从根Canvas开始,逐级向下遍历UI元素树,检查每个元素是否包含点击的屏幕坐标。这个过程是通过计算元素的位置和大小来实现的,而不是通过物理射线检测。

在uGUI中,射线检测主要用于3D物体与UI元素的交互,例如,当你想知道一个3D物体是否被点击时,你可能会使用射线检测。但是,对于UI元素之间的交互,uGUI主要依赖于位置和层次结构来确定点击事件的目标。

动静分离优点

优化UI渲染性能(UGUI层面)

  1. 减少网格重建(Rebatch)开销
    UGUI的Canvas下元素变化会触发整个Canvas的网格重建。动静分离后,动态元素(如滚动列表、动画按钮)与静态元素(如背景、文字标签)分属不同Canvas,动态Canvas仅需合并变化部分,避免静态元素重复参与重建,节省CPU计算资源
  2. 控制合批与DrawCall平衡
    动态元素单独Canvas会打断合批,增加DrawCall,但相比频繁重建的开销,整体性能可能更优。例如,一个界面中90%静态元素与10%动态元素分离后,动态Canvas的合并计算量大幅减少

合批规则

  1. 合批规则

    • 以Canvas为基本单位进行合批,子Canvas独立合批(无法与父Canvas合并)

    • 每个Canvas下的UI元素单独计算合批,跨Canvas无法合并

  2. 合批条件

    材质与纹理相同:相邻UI元素必须使用相同的材质(Material ID)和纹理(Texture ID)才能合批

    深度(Depth)连续: Depth值相邻且无中断(见下文Depth算法)

  3. Depth计算算法

    深度优先遍历:按Hierarchy从上到下顺序计算每个UI元素的Depth值

    • 不渲染的元素:Depth = -1(剔除)。

    • 无重叠元素:Depth = 0。

    • 与下层元素重叠:

      • 若可合批(同材质纹理),Depth = 下层Depth;

      • 若不可合批,Depth = 下层Depth + 1;

      • 与多个下层重叠时,取最大Depth值

  4. 排序与合并流程

    1. 按Depth升序排序 → 同Depth按Material ID排序 → 同材质按Texture ID排序→ 同纹理按Hierarchy顺序排序
    2. 遍历排序后的列表,合并相邻且材质纹理相同的元素为一个批次

UGUI的优化

UGUI(Unity GUI)是Unity的UI系统,优化方法包括:

  • 减少Draw Call:合并UI元素,使用图集(Atlas)。
  • 避免频繁重建Canvas:将动态UI和静态UI分开。
  • 使用对象池:复用UI元素,减少实例化和销毁的开销。
  • 禁用不可见UI:通过SetActive(false)或CanvasGroup隐藏UI。
  • 减少Raycast Target:不必要的UI元素禁用射线检测。