UGUI的Canvas Scaler

本文介绍了Unity中CanvasScaler组件的三种定位模式:恒定像素大小模式、随屏幕尺寸缩放模式及固定物理尺寸模式,并详细解释了每种模式的特点及应用场景,特别是针对手游项目的开发建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CanvasScaler
  • 三种定位模式
  • Constant Pixel Size
    • 恒定像素大小模式
    • Scale参数会作用于Canvas的游戏物体
    • 在该模式下屏幕尺寸发生什么变化,UI元素都不会改变
    • Reference Pixels Per Unit 参考像素单位,默认保持为1
  • Scale With Screen Size
    • 在手游项目开发中,使用该模式
    • UI元素的尺寸会跟随屏幕比例进行相应的自动缩放
    • Reference Resolution 参考分辨率,设置成项目开发时使用的分辨率,就会按照这个比例进行缩放
    • Screen Match Mode 屏幕匹配模式
      • Match Width Or Heigth 匹配宽度或高度
      • Expand扩大
      • Shrink 缩小
      • 当选中第一个时候,会出现Match滑块条,0-1代表宽高
      • 横屏游戏用Height,竖屏游戏用Width 以短方向匹配
  • 第三种是固定物理尺寸,使用很少
总结
  • 第一和第三都是固定模式,不适合手游项目的开发,由于屏幕分辨率不统一,经常用第二种开发
<think>我们正在分析UnityUGUICanvas的源码实现。根据用户提供的引用,特别是引用[2]提到“UGUI源码分析”,但引用内容中并未给出具体源码分析细节。因此,我们需要结合Unity官方提供的UGUI源码仓库进行说明。UnityUGUI的源码托管在GitHub上:https://github.com/Unity-Technologies/uGUI.git由于用户要求分析Canvas的源码实现,我们应关注Canvas组件相关的代码。在UGUI源码中,Canvas相关的核心代码位于:-`UnityEngine.UI/UI/Core/Canvas.cs`-另外,Canvas的渲染和更新机制可能还涉及`CanvasRenderer`、`CanvasUpdate`等。###核心功能分析1.**Canvas组件**:负责管理UI元素的渲染。它决定UI元素是渲染在屏幕空间还是世界空间,并处理渲染顺序(通过SortingLayer和OrderinLayer)。2.**Canvas的渲染流程**:-当Canvas组件的`renderMode`设置为`ScreenSpaceOverlay`时,UI元素直接在屏幕上渲染,不需要摄像机。-当设置为`ScreenSpaceCamera`或`WorldSpace`时,需要指定一个摄像机,UI元素将在这个摄像机所定义的视口中渲染。3.**Canvas的更新**:-UGUI使用脏标记系统(DirtyFlags)来标记需要更新的UI元素。当UI元素发生变化(如位置、大小、颜色等)时,会标记为脏,然后在下一帧进行重新构建(Rebuild)。-Canvas组件本身会注册到CanvasUpdateRegistry中,在渲染前执行重建(Rebuild)和布局(Layout)更新。###源码关键点在`Canvas.cs`中,我们可以找到以下关键部分:```csharpnamespaceUnityEngine.UI{[DisallowMultipleComponent][RequireComponent(typeof(CanvasRenderer))][AddComponentMenu("UI/Canvas",10)][ExecuteAlways]publicclassCanvas:Behaviour{//...省略部分代码...//渲染模式[SerializeField]privateRenderModem_RenderMode=RenderMode.ScreenSpaceOverlay;publicRenderModerenderMode{get{returnm_RenderMode;}set{m_RenderMode=value;}}//当渲染模式为ScreenSpaceCamera或WorldSpace时使用的摄像机[SerializeField]privateCameram_WorldCamera;publicCameraworldCamera{get{returnm_WorldCamera;}set{m_WorldCamera=value;}}//...其他属性和方法...//标记Canvas为脏,需要更新publicvirtualvoidRebuild(CanvasUpdateexecuting){if(executing==CanvasUpdate.Prelayout){//执行预布局更新}//...其他更新阶段...}//...其他代码...}}```###Canvas的更新机制Canvas的更新由`CanvasUpdateRegistry`管理。这个类维护了两个列表:需要布局重建的组件列表和需要图形重建的组件列表。在每一帧的预渲染阶段(通过`Canvas.willRenderCanvases`事件),这些重建操作会被执行。###性能优化相关-**避免频繁的Canvas重建**:因为重建操作(尤其是布局重建)可能很昂贵,所以应尽量减少UI元素的变动,尤其是涉及布局变化的操作。-**使用多个Canvas**:将频繁更新的UI元素和静态UI元素分开放在不同的Canvas上,可以减少重建的范围。因为每个Canvas独立重建,这样静态部分就不会被频繁重建影响。###引用说明根据引用[1][2][3][4][5],它们提供了关于Canvas组件的基础知识、优化方法和使用示例,但未深入源码。因此,我们的源码分析主要基于官方源码仓库。###相关问题§§相关问题§§1.Canvas的渲染模式有哪些?它们分别适用于什么场景?2.如何优化Canvas的重建性能?3.Canvas的脏标记系统是如何工作的?4.在UGUI中,CanvasUpdateRegistry的作用是什么?5.为什么需要将UI元素分层到多个Canvas上?</think>### Unity UGUI Canvas 源码分析 #### 1. **Canvas 核心功能** CanvasUGUI 的渲染容器,负责管理 UI 元素的绘制顺序和渲染模式。关键源码位于: - `Canvas.cs`(核心逻辑) - `CanvasRenderer.cs`(渲染实现) - `CanvasUpdateRegistry.cs`(更新调度) 在 `Canvas.cs` 中,核心属性包括: ```csharp public class Canvas : Behaviour { public RenderMode renderMode; // 渲染模式(ScreenSpaceOverlay/ScreenSpaceCamera/WorldSpace) public Camera worldCamera; // 关联的摄像机 public float planeDistance; // UI平面与摄像机的距离 // ... } ``` [^2] #### 2. **渲染流程** - **脏标记系统**:当 UI 元素属性(位置、颜色等)变化时,标记 `Graphic` 为脏,触发重建。 - **渲染队列**:通过 `CanvasRenderer` 将顶点数据提交到 Unity 渲染管线。 - **层级排序**:由 `SortingLayer` 和 `Order in Layer` 控制绘制顺序。 关键代码片段(简化): ```csharp // CanvasRenderer.cs protected void SetVertices(List<UIVertex> vertices) { // 将顶点数据传递给底层渲染系统 InternalSetVertices(vertices); } ``` #### 3. **性能优化机制** - **静态批处理**:未变化的 UI 元素合并批次(通过 `CanvasRenderer.cull` 检测)。 - **动态重建**:仅重绘脏区域(由 `CanvasUpdateRegistry` 管理): ```csharp // CanvasUpdateRegistry.cs private void PerformUpdate() { // 遍历所有脏元素并重建 foreach (var element in m_LayoutRebuildQueue) { element.Rebuild(CanvasUpdate.Layout); } } ``` [^1][^2] #### 4. **与 Canvas Scaler 协同** `CanvasScaler.cs` 处理分辨率适配: - 根据 `Screen.width/height` 动态缩放 UI。 - 支持三种模式:`Constant Pixel Size`、`Scale with Screen Size`、`Constant Physical Size`。 #### 5. **关键设计思想** 1. **事件驱动更新**:基于 `UnityEngine.EventSystems` 的事件系统触发 UI 刷新。 2. **组件解耦**:`Canvas` 仅管理容器状态,具体渲染由 `Graphic` 派生类(如 `Image`)实现。 3. **异步重建**:通过 `Canvas.willRenderCanvases` 事件在渲染前统一处理更新。 > 提示:完整源码可查看 [Unity UGUI GitHub 仓库](https://github.com/Unity-Technologies/uGUI.git)[^1]。 --- ### 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值