更新

  • 2019/09/12 增加扩展链接
  • 2019/06/30 初次发布

介绍

有时需要将相机视口大小调整为 UI 控件的大小与位置,将 3D 模型显示在 UI 所在的区域。

实现起来很简单,只要将 UI 控件的大小与位置由 UI 坐标转换为屏幕坐标,然后设置相机的视口属性即可。

如果需要在不改变 UI 区域大小的同时实现将显示区域扩展到全屏,可以参考:

实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
using UnityEngine;

public static class RectTransformToViewport
{
    public static Rect Convert(RectTransform rectTransform, Camera camera)
    {
        var corners = new Vector3[4];
        rectTransform.GetWorldCorners(corners);
        var bottomLeft = camera.WorldToViewportPoint(corners[0]);
        var topLeft = camera.WorldToViewportPoint(corners[1]);
        var topRight = camera.WorldToViewportPoint(corners[2]);
        var bottomRight = camera.WorldToViewportPoint(corners[3]);

        var rect = new Rect();
        rect.x = Mathf.Clamp01(bottomLeft.x);
        rect.y = Mathf.Clamp01(bottomLeft.y);
        rect.width = Mathf.Clamp01(topRight.x - topLeft.x);
        rect.height = Mathf.Clamp01(topRight.y - bottomRight.y);

        return rect;
    }
}

注意事项

UGUI 的控件(如 ScrollView)大小与位置更新也在 Update 事件中,因此不能依赖于不同脚本的 Update 事件顺序设置大小与位置,否则有时会出现大小与位置不正确。

有两种解决方法:

  1. 调用 RectTransform.ForceUpdateRectTransforms,强制刷新 UI
  2. 使用协程等方法延迟一帧显示,要求 UI 上也必须配合将内容隐藏,下一帧再显示。