Unity:如何使用 C# 使 Canvas UI 响应所有屏幕

Posted

技术标签:

【中文标题】Unity:如何使用 C# 使 Canvas UI 响应所有屏幕【英文标题】:Unity: How to make Canvas UI Responsive for all screens using C# 【发布时间】:2021-05-30 06:53:57 【问题描述】:

我是 Unity 新手。如何使 Canvas UI 像小按钮的小屏幕和大按钮的大屏幕一样具有响应性。但是当我测试小屏幕中的小按钮很大而大按钮是大屏幕时很小。我只是想扭转这个,所以它会响应,有可能吗?

【问题讨论】:

【参考方案1】:

在 Unity UI 中实现完全可扩展设计的诀窍是永远不要对任何东西使用像素大小。 Start 将所有矩形完全展开(所有边距为 0)并使用锚点按您的方式工作(使用 alt 强制边距归零)

我还可以推荐一个我写的小工具RectAnchorHelper。 如果您点击链接, 您可能会收到 [exposemethodineditor] 依赖项的错误,只需将其注释掉,或下载整个 repo。我正在粘贴完整的类代码,并在下面剥离了依赖项。

RectAnchorHelper 的作用是公开四个滑块,让您以完全比例的方式调整您的位置,因此您可以在不参考像素大小的情况下设计您的 UI。

等式的另一部分是使用画布缩放器设置为按 Rakib 提到的屏幕大小缩放

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif

[ExecuteInEditMode]
public class RectAnchorHelper : MonoBehaviour

    RectTransform rect  get  if (_rect == null) _rect = GetComponent<RectTransform>(); return _rect;  
    RectTransform _rect;
    [SerializeField] bool edit;
    [SerializeField] bool _symmetricalXMode;
    [SerializeField] bool _symmetricalYMode;
    public bool symmetricalXMode  get  return _symmetricalXMode;  set  _symmetricalXMode = value; CheckAndSet();  

    public bool symmetricalYMode  get  return _symmetricalYMode;  set  _symmetricalYMode = value; CheckAndSet();  

    [Range(0, 1)]
    [SerializeField] float _xAnchorMin;
    [Range(0, 1)]
    [SerializeField] float _xAnchorMax = 1;
    [Range(0, 1)]
    [SerializeField] float _yAnchorMin;
    [Range(0, 1)]
    [SerializeField] float _yAnchorMax = 1;
    public float xAnchorMin  get  return _xAnchorMin;  set  _xAnchorMin = value; CheckAndSet();  

    public float xAnchorMax  get  return _xAnchorMax;  set  _xAnchorMax = value; CheckAndSet();  

    public float yAnchorMin  get  return _yAnchorMin;  set  _yAnchorMin = value; CheckAndSet();  

    public float yAnchorMax  get  return _yAnchorMax;  set  _yAnchorMax = value; CheckAndSet();  

    // [SerializeField] [HideInInspector] Vector2 offsetMin;
    // [SerializeField] [HideInInspector] Vector2 offsetMax;
    public void SetMargin(float f)  margin = f; 

    [Range(-1, 15)]
    [SerializeField] float _margin = -1;
    public float margin  get  return _margin;  set  _margin = value; CheckAndSet();  
    void CheckAndSet()
    
        if (symmetricalXMode) _xAnchorMax = 1 - _xAnchorMin;
        if (symmetricalYMode) _yAnchorMax = 1 - _yAnchorMin;
        SetValues();

    
    void Reset()
    
        PrepareRect();
        GetValues();
    
    void OnValidate()
    
        if (symmetricalXMode) xAnchorMax = 1 - xAnchorMin;
        if (symmetricalYMode) yAnchorMax = 1 - yAnchorMin;
        //      if (Application.isPlaying) return;
#if UNITY_EDITOR
        bool isSelected = false;
        foreach (var s in Selection.gameObjects)
        
            if (s == gameObject) isSelected = true;
        
        if (!isSelected)  edit = false; return; 
        Undo.RecordObject(rect, "RectAnchor");
#endif
        if (edit)
        
            SetValues();
        
        else
            GetValues();
    

    void SetValues()
    
        rect.anchorMin = new Vector2(xAnchorMin, yAnchorMin);
        rect.anchorMax = new Vector2(xAnchorMax, yAnchorMax);
        if (margin != -1)
        
            rect.offsetMin = new Vector2(margin * margin, margin * margin);
            rect.offsetMax = new Vector2(-(margin * margin), -(margin * margin));
        
    
    void GetValues()
    
        _xAnchorMin = rect.anchorMin.x;
        _xAnchorMax = rect.anchorMax.x;
        _yAnchorMin = rect.anchorMin.y;
        _yAnchorMax = rect.anchorMax.y;
    

    void PrepareRect()
    
        rect.anchorMin = Vector2.zero;
        rect.anchorMax = Vector2.one;
        rect.offsetMax = Vector2.zero;
        rect.offsetMin = Vector2.zero;
        rect.localScale = Vector3.one;
    

当然你可以在没有我的课程的情况下完成这一切,但我个人发现输入浮点值相当乏味,上面的代码将为你提供易于视觉编辑的滑块。

【讨论】:

【参考方案2】:

在 Canvas 中,您有一个 CanvasScaler

    设置 UI 缩放模式 -> 随屏幕大小缩放 输入基本分辨率(例如:1080x1920 适用于移动设备)并确保您的游戏窗口采用该分辨率 相应地设置匹配(例如:对于纵向分辨率,我使用 1)

【讨论】:

你应该像这样设置你的画布,但是如果你没有正确设置 UI 元素的矩形变换的锚点,缩放将不正确。设置元素的锚点,而不是在 480x6401080x1920 之间更改游戏窗口大小,然后检查缩放是否正确。如果您将锚点移动到变换点(所有 4 个都匹配),当屏幕尺寸发生变化时,方面将受到保护。

以上是关于Unity:如何使用 C# 使 Canvas UI 响应所有屏幕的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Canvas 适应不同的手机分辨率? Unity3d

unity UGUI如何获取鼠标指针所在位置的UI对象

unity中如何将Ui Image占满界面

Unity中的UI

Unity实现一打开游戏就播放视频动画

Unity5.3——UI之Canvas